在8年以前,Yahoo团队曾经对网页中的缓存作了比较详尽的研究,可是随着互联网的高速发展,研究数据发生了一些变化。这篇文章主要是Facebook的web团队对如今缓存状况一些数据收集和研究。包括PC和移动端资源被缓存的时间以及资源在存在的时间。网页缓存是性能优化很重要的因素,值得一读。 jquery
能力有限,若有翻译错误的地方,欢迎随时找我交流,我会及时更正:)android
网页加载速度是每一个网站都应该重视的因素。可是每每被你们忽略。缓存是一个提高网站访问速度很是重要的因素(由于用户在下次访问的时候不须要从新计算或者下载已经缓存的资源)web
咱们团队(facebook web团队)最近针对目前facebook.com没有缓存的现状进行了一番讨论,主要问题是:在facebook,.咱们天天都会发布两个版本,怎么样才能令缓存更有效率?怎么样的缓存策略才适合咱们?chrome
在找解决方案的时候, 咱们发现雅虎性能优化研究博客上已经有了一篇关于性能研究的文章。数据库
可是令咱们很是吃惊的是:20%的页面访问是在空缓存的状况下进行的。可是这个研究结果距离如今有8年了,那个时代刚发布IE7,jquery也刚发布第一个版本,因此咱们决定从新研究一下,看如今是否是有所改善。浏览器
在以前的研究当中,Yahoo在服务器建立了HTTP头设置了图片的过时时间和上次修改时间,若是图片没有发生改变,就用GET请求发送给服务器一个最后修改时间的信息,若是图片没有修改,就返回304(没有修改)来替换200(请求成功)。由于服务器能够记录浏览器请求的请求状态,因此Yahoo用服务器日志来统计缓存的用户数。缓存
像那样的研究方法同样,咱们建立了一个既能发送图片请求也能在数据库当中记录日志的PHP终点。这张图片用http头信息来控制浏览器的缓存和其余经过代理产生的缓存。以后在用户请求图片的时候记录这些信息。性能优化
这个图片HTTP头信息的设置是这样的:服务器
可是由于一些已知的BUG,咱们在IE7和IE8中把两个属性替换成了下面这样:ide
当浏览器发送请求给图片时候,将会发生两件事情:
1。由于浏览器历来没有打开过这张图片,因此没有额外的头信息,服务器将返回一个状态码:200 Success 接着返回图片数据给浏览器,以后浏览器会缓存文件的HTTP头信息当中的Last-Modified(文件最后修改时间)和ETag(被请求变量的实体值)
2。浏览器检查if-none-match或者if-modified-since头信息,若是以前有打开过。将会不加载图片数据直接返回Status:304 Not Modified(没有更新)。同时咱们把Last-Moidified头信息用$header['if-modified-since']替换掉$now(),因此每次返回的内容都将是同样的。
如今剩下问题是咱们在哪里应用这张图片,最后咱们决定在Facebook的搜索条下面包含一个img标签,这样每次facebook加载的时候都会渲染这张图片。在整个页面从新加载的时候,资源将会根据缓存的头信息进行加载。这将是最好的方式来测试咱们的想法。
在确保endpoint能够正常记录请求、图片标签能够正常访问了以后,咱们正式开始了此次研究!
在数周的数据收集以后,咱们决定来研究一下7天最后比较有价值的数据。数据的统计结果依旧让咱们感到吃惊:依旧有25.5%的请求是空缓存的。为了让数据看起来更清晰,咱们分隔了PC和手机的统计数据,可是数据依旧差很少:PC有24.8%而手机端有26.9%是空缓存的。这个结果不太符合咱们预期,因此咱们更加深刻的研究了这个数据。
把PC端的浏览器分开来统计可能更加清楚:
根据上面一周的数据来看:用户用chrome和opera缓存的概率更大。你可能注意到你这个图表中并无firefox浏览器的数据,那是由于firefox 31版本以及更早期的版本在咱们的统计中有80%的缓存几率,可是在32版本和更高的版本当中有很明显的降低。那是由于firefox的缓存策略和咱们的统计方法有点冲突(http://www.janbambas.cz/new-firefox-http-cache-enabled/),
因此咱们就干脆去掉了firefox浏览器的数据统计。
好了,如今让咱们来看看移动端的数据:
能够看到,大部分浏览器的缓存比例是在68%和84%之间。移动平台的数据差异仍是挺大的,咱们想可能都是比较低端的移动设备(https://code.facebook.com/posts/307478339448736/year-class-a-classification-system-for-android/)。除此之外数据跟桌面端仍是比较类似的。
下面这个图分别是移动端和手机端空缓存用户所占的比例:
平均来看,有44.6%的用户是空缓存的,这个也很符合Yahoo团队在2007年作的研究。
到这里,文章尚未完结。在Facebook,咱们迭代速度很是快,天天几乎都会发布两个版本。这个驱动咱们去思考,多长时间的缓存设置适合咱们呢?咱们将if-modified-since这个文件头返回的时间减去当前时间来寻找答案。
因此咱们根据上面的方法,咱们统计了从第一次正常请求到发生304请求的时间(这说明了用户从没有缓存到有缓存经历了多长时间),下面是数据生成的图标:
横轴是以小时为单位的时间值,垂直竖线P50和P75表示在某一时间内缓存请求所占的比例,例如P50告诉咱们在47小时的时候有50%的请求是有缓存的,一样,p75意味着75%的请求将是有缓存的。
移动端的测试数据告诉咱们大概在12小时的时候有50%的请求是有缓存的。
整体来看咱们的统计跟2007年是比较类似的,若是咱们firefox浏览器(32和更高版本)不计入统计的话:此次有缓存的比例最高点是84.1%,高于2007年的80%。
另外一方面,缓存的存在时间并非太长。基于咱们的研究,虽然在一个新版本发布的47小时以后有42%的请求将会带有缓存,可是这个缓存资源在电脑上存在时间也大概是这个时间。这个新的发现,对其余网站颇有参考意义。
为何缓存存在的时间不是太长?其实很是容易理解,从互联网的发展来讲,网站的体积从2007到如今发生了不小的变化。拿2007年年来讲,那时候咱们家里的网速大概是2.5M,Yahoo的首页有168.1KB。如今个人手机都有了8G下行,Yahoo首页已经变到768KB。如今市面上网页的平均大小已经超过1MB了,这将给咱们的浏览器的良好运做带来很大的压力(译者注:由于须要缓存的资源太多,超过浏览器设置的默认资源缓存大小会自动删掉早期的一些缓存文件,例如ie默认的是50MB,而chrome的是320MB)。
所以合理利用浏览器缓存比8年以前更加有意义。
最佳实践告诉咱们:尽可能用外链样式表和JS、让headers设置Cache-Control and ETag,并尽量的压缩咱们的数据、用不一样的网址管理缓存、分割须要频繁更新的资源。这些优化方法不只适用于像facebook这样规模的项目,其余网站也能够应用它们。虽然咱们的更新频率会对缓存的优化带来负面的影响,可是这个不是本次文章所研究的重点。事实上,咱们已经开始运用此次的研究成果来让全部访问facebook的用户收益。
Chromium cache metrics
原文:https://code.facebook.com/posts/964122680272229/web-performance-cache-efficiency-exercise/
翻译:TGideas - Allan