8年前,雅虎团队对网页缓存做了比较详细的研究,但是随着互联网的快速发展,研究数据发生了一些变化。这篇文章主要是Facebook的web团队对目前缓存情况的一些资料收集和研究。包括PC端和移动端资源被缓存的时间和资源存在的时间。Web缓存是性能优化的重要因素,值得一读。能力有限,如有翻译错误,欢迎与我交流,我会及时改正:)文:网页加载速度是每个网站都应该关注的一个因素。但往往被大家所忽视。缓存是提高网站访问速度的一个非常重要的因素(因为用户下次访问时不需要重新计算或下载缓存的资源)。我们团队(facebookwebteam)最近针对facebook.com没有缓存的现状做了一个调查经过一番讨论,主要问题是:在facebook上,我们每天发布两个版本,如何让缓存更高效?什么样的缓存策略适合我们呢?在寻找解决方案时,我们发现在雅虎性能优化研究博客上已经有一篇关于性能研究的文章。但令我们大吃一惊的是:20%的页面访问是在空缓存下进行的。但这个研究成果距离现在还有8年。当时IE7刚刚发布,jquery第一版也刚刚发布,所以我们决定重新研究一下,看看现在有没有改进。重新研究:在之前的研究中,雅虎在服务器上创建了一个HTTP头来设置图片的过期时间和最后修改时间。如果图片没有变化,它会使用GET请求向服务器发送一个***修改时间信息。如果图片没有修改过,则返回304(未修改)替换200(请求成功)。因为服务器可以记录浏览器请求的请求状态,所以雅虎使用服务器日志来统计缓存的用户数。与该研究方法一样,我们创建了一个PHP端点,用于发送图像请求和数据库中的日志。此图像使用http标头通过代理控制浏览器缓存和其他缓存。然后在用户请求图像时记录此信息。这张图片的HTTP头信息设置如下:但是因为一些已知的bug,我们将IE7和IE8中的两个属性替换为如下:当浏览器向图片发送请求时,会发生两件事:1.因为浏览器从来没有打开过这张图片,所以没有额外的header信息,服务器会返回一个状态码:200Success然后将图片数据返回给浏览器,然后浏览器会缓存该图片的HTTPheader信息fileLast-Modified(文件的最新修改时间)和ETag(请求变量的实体值)2.浏览器检查if-none-match或者if-modified-since头信息,如果之前打开过。它将返回Status:304NotModified(未更新)而不加载图像数据。同时,我们用$header['if-modified-since']将Last-Moidified头信息替换为$now(),所以每次返回的内容都是一样的。现在剩下的问题是我们在哪里应用这个图像,***我们决定在facebook搜索栏下包含一个img标签,这样每次facebook加载时都会呈现这个图像。当整个页面重新加载时,会根据缓存的头部信息加载资源。这将是测试我们想法的最佳方式。在确保端点可以正常记录请求,图片标签可以正常访问后,我们正式开始本次调研!结果:经过几周的数据收集,我们决定查看7天***更有价值的数据。数据的统计结果还是让我们大吃一惊:25.5%的请求还在空缓存中。为了让数据看起来更清晰,我们将PC和移动统计数据分开,但数字仍然几乎相同:PC为24.8%,移动为26.9%。这个结果没有达到我们的预期,所以我们更深入地研究了数据。把PC端的浏览器分开可能会更清晰:根据前一周的数据:用户更倾向于使用chrome和opera来缓存。你可能会注意到你的图表中没有firefox浏览器的数据,那是因为firefox31及更早的版本在我们的统计中有80%的缓存概率,但在32及之后的版本有明显的下降。那是因为firefox的缓存策略和我们的统计方法(http://www.janbambas.cz/new-firefox-http-cache-enabled/)有冲突,所以我们干脆去掉了firefox浏览器的数据统计。好了,现在我们来看一下移动端的数据:我们可以看到大部分浏览器的缓存比例都在68%到84%之间。移动平台的数据还是有很大差异的。我们认为它可能是相对低端的移动设备(年级:Android的分类系统)。此外,数据与桌面的数据相对相似。下图是移动端和移动端缓存为空的用户比例:平均有44.6%的用户缓存为空,这也符合雅虎团队2007年的研究。更进一步:此时,文章还没有结束。在Facebook,我们迭代非常快,几乎每天都会发布两个版本。这就促使我们思考,缓存设置多久才适合我们呢?我们从if-modified-since文件头返回的时间中减去当前时间来找到答案。那么按照上面的方法,我们统计了从第一次正常请求到304请求的时间(这个显示用户从无缓存到有缓存的时间),下面是数据生成的图标:横轴是以小时为单位的时间值。垂直竖线P50和P75表示一定时间内缓存请求的比例。例如,P50告诉我们50%的请求在47小时被缓存。同样,p75意味着75%的请求将被缓存。移动端的测试数据告诉我们,大约有50%的请求在12小时内被缓存。实际应用:总体来说,我们的统计和2007年差不多,如果不统计我们的firefox浏览器(32及以上版本):这次的缓存比例最高点是84.1%,高了80%2007年。另一方面,缓存不会存在太久。根据我们的研究,虽然42%的请求会在新版本发布后的47小时内被缓存,但缓存的资源会在计算机上存在大约这段时间。这一新发现对其他网站具有很大的参考价值。为什么缓存不会存在太久?其实很好理解。从互联网的发展来看,网站的规模从2007年到现在发生了很大的变化。以2007年为例。那时候我们家的网速大概是2.5M,雅虎的主页是168.1KB。现在我的手机下行8G,雅虎主页变成768KB。现在市面上的网页平均大小已经超过1MB,这会对我们浏览器的良好运行造成很大的压力(译者注:因为需要缓存的资源太多,超过了默认的资源缓存大小浏览器设置它会自动删除一些早期的缓存文件,比如ie默认是50MB,chrome默认是320MB)。因此,合理使用浏览器缓存比8年前更有意义。***实践告诉我们:尽量使用外部链接样式表和JS,让headers设置Cache-Control和ETag,尽可能的压缩我们的数据,使用不同的url管理缓存,划分需要更新的资源频繁地。这些优化方法不仅适用于Facebook这种规模的项目,其他网站也可以借鉴。虽然我们的更新频率会对缓存优化产生负面影响,但这不是本文的重点。事实上,我们已经开始使用这项研究的结果来造福所有访问facebook的用户。
