资讯专栏INFORMATION COLUMN

网页性能: 缓存效率实践

Ashin / 2226人阅读

摘要:上图显示了桌面浏览器一周内的缓存命中率。和早期版本用当前方法测试的缓存命中率为,过版本及以上却大大的下降。实际应用总的来看缓存命中率相比年有所提高。如果忽略及以上版本无法测试,这样缓存命中率由年的左右提高到现在的。

[]()

Ryan Albrecht
caisijie 翻译于2015/12/21

任何网站都会考虑性能,不管是当地的理发店或者有巨大知识库的维基百科。这是一个无法被忽略的需求。因此缓存变得尤其重要 —— 一种让网站变快的极佳途径,通过保存部分数据,使得下次访问时不用再次计算或者下载。

我们团队最近在讨论Facebook.com没有被缓存的的部分网页,问题就来了:Facebook每两天发布一次代码,缓存的效率有多高?我们是否发布代码太频繁导致浏览器的缓存没有充分利用?为了找到答案,我们在Yahoo"s Performance Research blog 发现一篇研究关于浏览器缓存对网页性能的影响的文章。

我们从中惊讶的发现一个悲观的结论:有20%的页面访问没有经过缓存。但是这份研究至今已超过8年,那时候浏览器还无法显示如顶部截图那样的瀑布式流量图,那时候IE7和jQuery才发布了几个月。我想忘记这份研究吧,jQuery 1.0 —— 老掉牙了。为了得到更精确的结果,我们决定重新测试看看事情是否有所改观。

重开课题

在原来的研究中,Yahoo构造的一种带特殊头的图片。这些头会告诉浏览器如果同样的图片被请求两次,不会进行正常的请求,而是根据图片是否变动这个条件发送GET请求。这种GET请求会把最后修改时间的头传给服务器,如果请求时间和图片最后修改时间间隔太小,则返回304没有修改而是不是200成功。Yahoo最后查看服务器日志进行分析。

与之类似,我们构建了一个PHP终端来提供图片以及向数据库记录请求。图片附带特殊的头来控制浏览器的缓存和中间件的缓存,而且我们会在请求同时记录所有头的信息。而响应头如下:

Cache-Control: no-cache, private, max-age=0
ETag: abcde
Expires: Thu, 15 Apr 2014 20:00:00 GMT
Pragma: private
Last-Modified: $now // RFC1123 format

在IE7和IE8下,为了绕过一些已知问题,需要特殊修改:

Cache-Control: private, max-age=0
Pragma: no-cache

当浏览器请求图片时,会没有附带或者附带一到两个额外头部:

没有额外头部,因为浏览器并不认识这个图片。我们返回Status: 200 Success 以及 image data ,然后浏览器会缓存这些内容。并生成Last-Modified 时间和 ETag值会已备下次使用。

if-none-match 和 if-modified-since 头的一个或两个,它说明浏览器之前获取过图片。服务器会返回Status: 304 Not Modified并且不包含图片数据。我们还把Last-Modified头设置为$header["if-modified-since"]而不是$now,这样浏览器每次就能获得相同的响应内容。

最后的问题就是什么时候和在哪里发送图片请求。我们决定在Facebook搜索条旁边包含一个img标签,这样Facebook每次重载的时候就会渲染。在一个整个页面的重载中,内存资源会被卸载,然后浏览器根据缓存头重新请求CSS,JavaScript和我们的图片。所以这是测量缓存是否工作的最佳位置。

在准备好终端去记录请求日志和让img标签去发送请求之后,我们马上开始...

研究结果

经过几周的数据收集和填满缓存,对比最后超过7天的数据。初次结果同样出乎意料:25.5%的请求没有命中缓存。我们把数据按接口分类,桌面和移动设备,但是结果相似:桌面版24.8%以及移动版的26.9%请求没有命中缓存。这不是期望的结果,所以我们继续深入调试。

把桌面数据按浏览器划分后变得一目了然。

上图显示了桌面浏览器一周内的缓存命中率。使用Chrome和Opera显然从浏览器缓存受益更多。你可能注意到Fireforx并没有出现在表中,这是有原因的。Firefox v31和早期版本用当前方法测试的缓存命中率为80%,过v32版本及以上却大大的下降。v32 版本说明解释了缓存后台会 记录并重用最近的响应头。如果重用响应,我们的终端就没法收到请求并记录日志。这样测试会错误的认为Firefox表现糟糕。但实际上仍在命中本地缓存;只是无法统计信息。考虑到这点,我们把Firefox排除在测试结果之外。

让我们看看移动端的情况

不同产品的缓存命中在68%和84%之间浮动,和之前的线差不多。移动端的变动性更多,因为许多不同  year class 的设备在访问移动网页,而且每一个浏览器版本都有一个可能的范围。这些数字普遍比桌面版的低但是排序基本一致。

我们还可以看看不同用户命中空缓存的比例

平均44.6%的用户获取了空缓存。这佐证了Yahoo在2007年关于每个用户命中率的结果。

更进一步

还没有完呢。在Facebook,我们希望小步快走的每天两次地发布包含当天完成的所有优秀功能。这就引出一个问题:浏览器缓存生命周期是多少?我们可以通过把请求头if-modified-since的值减去当前时间值,这样就可以得到这个用户命中缓存的存活时间。

所以我们发掘数据。仍然是最近一周的数据,我们生成描述缓存持续命中(请求返回304)时间分布的柱状图。换一种说法,每次重新获取图片的间隔有多长。

横轴 duration 单位是小时,竖线 p50_(百分之50), _mean_(平均)和 _p75(百分之75)分别表示对应请求比例的缓存时间。比如,_p50 表示50%的请求在命中最多47小时之前生成的缓存,类似的 p75 表明25%的请求的缓存存在的时间至少有260个小时。在移动端做同样的分析显示有50%的请求的缓存不会超过12个小时。

实际应用

总的来看缓存命中率相比2007年有所提高。如果忽略Firefox v32及以上版本(无法测试),这样缓存命中率由2007年的80%左右提高到现在的84.1%。另一方面,缓存保持活跃的时间并不是很长。根据我们的研究,在桌面版,有42%概率任何请求的缓存的存在时间不超过47小时。这是一个新的维度,而且在某些网站影响突出。

很容易解释为什么缓存存在时间通常很短。看看因特网如何传输和网页大小size从2007年至今的变化。在2007年,家庭有线带宽是2.5Mbps,Yahoo主页168.1KB。如今,我有8Mbps的LTE移动下载带宽,Yahoo主页是768KB。现在网页平均大小是1MB,对浏览器优化造成了更大的压力。

因此利用好浏览器缓存仍然重要,如果用好带来的收益也会比8年前更大。我们的最佳实践是使用外部样式和脚本,包含Cache-Control和Etag头,传输层数据压缩,使用URL使缓存资源失效,把平凡更新的资源和稳定资源分开。所有这些技术都能在任何网站协同工作,而不单单是Facebook。我们一开始担心自己的发布流程会给缓存性能带来负面影响,但结果并不是这样。实际上,我们使用这份数据专注于改进让所有人访问www.facebook.com都能通过缓存。真是有意思的一次缓存挖掘之旅。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/61762.html

相关文章

  • 网页性能缓存效率实践

    摘要:上图显示了桌面浏览器一周内的缓存命中率。和早期版本用当前方法测试的缓存命中率为,过版本及以上却大大的下降。实际应用总的来看缓存命中率相比年有所提高。如果忽略及以上版本无法测试,这样缓存命中率由年的左右提高到现在的。 [showImg(https://segmentfault.com/img/remote/1460000006788057);]() showImg(https://seg...

    anRui 评论0 收藏0
  • 前端性能优化

    摘要:端优谈谈关于前端的缓存的问题我们都知道对页面进行缓存能够有利于减少请求发送,从而达到对页面的优化。而作为一名有追求的前端,势必要力所能及地优化我们前端页面的性能。这种方式主要解决了浅谈前端中的过早优化问题过早优化是万恶之源。 优化向:单页应用多路由预渲染指南 Ajax 技术的出现,让我们的 Web 应用能够在不刷新的状态下显示不同页面的内容,这就是单页应用。在一个单页应用中,往往只有一...

    Dean 评论0 收藏0
  • 前端优化 - 收藏集 - 掘金

    摘要:虽然有着各种各样的不同,但是相同的是,他们前端优化不完全指南前端掘金篇幅可能有点长,我想先聊一聊阅读的方式,我希望你阅读的时候,能够把我当作你的竞争对手,你的梦想是超越我。 如何提升页面渲染效率 - 前端 - 掘金Web页面的性能 我们每天都会浏览很多的Web页面,使用很多基于Web的应用。这些站点看起来既不一样,用途也都各有不同,有在线视频,Social Media,新闻,邮件客户端...

    VincentFF 评论0 收藏0
  • JHipster技术简介

    摘要:本文简单介绍是什么,为什么用,怎么用。技术栈是什么是一个开发平台,用于生成,开发,部署和。实现需定制化源码。 本文简单介绍Jhipster是什么,为什么用Jhipster,怎么用Jhipster。 WHAT - 技术栈 JHipster是什么 JHipster是一个开发平台,用于生成,开发,部署Spring Boot + Angular/React Web Application和Sp...

    hightopo 评论0 收藏0
  • 精读《高性能 javascript》

    摘要:嵌套对象成员会造成重大性能影响尽量少用。一般来说你可以通过这种方法提高代码的性能将经常使用的对象成员数组项和域外变量存入局部变量中。在反复访问的地方使用局部变量存放引用小心地处理集合因为他们表现出存在性总是对底层文档重新查询。 前言 本期我来给大家推荐的书是《高性能JavaScript》,在这本书中我们能够了解 javascript 开发过程中的性能瓶颈,如何提升各方面的性能,包括代码...

    caohaoyu 评论0 收藏0

发表评论

0条评论

Ashin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<