迅维网

查看: 1163|回复: 0
打印 上一主题 下一主题

浏览器缓存知识归纳ub11.info

[复制链接]
跳转到指定楼层
1#
发表于 2016-7-28 07:37:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 来自: 中国 来自 中国

马上注册,获取阅读精华内容及下载权限

您需要 登录 才可以下载或查看,没有帐号?注册

x
浏览器缓存(Browser Catching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览。 —-摘自《百度百科》

浏览器缓存是提升网页性能的一大利器,但是,也是一把双刃剑。利用的好网页的性能会有大幅度提升,服务器的压力也会减小。利用的不好,也会遇到很多的问题。本文结合浏览器缓存的知识,结合真实案例进行分析,希望对读者有所帮助。

浏览器缓存分类

浏览器缓存分为强缓存和协商缓存,浏览器加载一个页面的简单流程如下:

浏览器先根据这个资源的http头信息来判断是否命中强缓存。如果命中则直接加在缓存中的资源,并不会将请求发送到服务器。

如果未命中强缓存,则浏览器会将资源加载请求发送到服务器。服务器来判断浏览器本地缓存是否失效。若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源。
如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。

强缓存

命中强缓存时,浏览器并不会将请求发送给服务器。在Chrome的开发者工具中看到http的返回码是200,但是在Size列会显示为(from cache)

强缓存

强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。
Expires

该字段会返回一个时间,比如Expires:Thu,31 Dec 2037 23:59:59 GMT。这个时间代表着这个资源的失*词语被过滤*间,也就是说在20371231235959秒之前都是有效的,即命中缓存。这种方式有一个明显的缺点,由于失*词语被过滤*间是一个绝对时间,所以当客户端本地时间被修改以后,服务器与客户端时间偏差变大以后,就会导致缓存混乱。于是发展出了Cache-Control
Cache-Control

Cache-Control是一个相对时间,例如Cache-Control:3600,代表着资源的有效期是3600秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。

Cache-ControlExpires可以在服务端配置同时启用或者启用任意一个,同时启用的时候Cache-Control优先级高。

协商缓存

若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据http头信息中的Last-Modify/If-Modify-SinceEtag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源。
Last-Modify/If-Modify-Since

浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-ModifyLast-modify是一个时间标识该资源的最后修改时间,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT
Last-Modify

当浏览器再次请求该资源时,上送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
If-Modify-Since

如果命中缓存,则返回http304,并且不会返回资源内容,并且不会返回Last-Modify。由于对比的服务端时间,所以客户端与服务端时间差距不会导致问题。但是有时候通过最后修改时间来判断资源是否修改还是不太准确(资源变化了最后修改时间也可以一致)。于是出现了ETag/If-None-Match

ETag/If-None-MatchLast-Modify/If-Modify-Since不同的是,Etag/If-None-Match返回的是一个校验码(ETag: entity tag)。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化*。服务器根据浏览器上送的If-None-Match值来判断是否命中缓存。
ETag

* ETag扩展说明

我们对ETag寄予厚望,希望它对于每一个url生成唯一的值,资源变化时ETag也发生变化。神秘的Etag是如何生成的呢?以Apache为例,ETag生成靠以下几种因子
文件的i-node编号,此i-node非彼iNode。是Linux/Unix用来识别文件的编号。是的,识别文件用的不是文件名。使用命令’ls I’可以看到
文件最后修改时间
文件大小

生成Etag的时候,可以使用其中一种或几种因子,使用抗碰撞散列函数来生成。所以,理论上ETag也是会重复的,只是概率小到可以忽略。
生产问题分析

背景:某次投产,某系统投产后由于强缓存设置时间不恰当导致变更的功能没有体现。后来通过变更文件路径强行解决问题。
变更上下文根,导致URL变化一定可以解决问题。但我们不可能每一次都这么做;还有,在浏览器端关闭缓存、或者清除缓存后再继续浏览、同时使用Ctrl+F5刷新,也可以解决问题,但是我们也不可能让每一个客户在投产后都做一次这个操作。

那我们怎么办呢?从问题原因来看,是将经常变化的资源缓存时间设置的过长导致的。理论上来讲,只要正确划分经常变化资源与不经常变化资源就可以解决问题。但是谁也不能保证不经常变化的资源就一定不会变化。
万一不经常变化的资源变更了怎么办呢?在资源请求的URL中增加一个参数,比如:css/main.css?v=201601058.ytABC3Aw0QiDcQ。这个参数是一个版本号,客户化在js代码中,每一次投产的时候变更一下,当这个参数变化的时候,强缓存都会失效并重新加载。这样一来,即使是不常变化的资源,投产以后也需要重新加载。这样就完美的解决了问题。


您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长提醒 上一条 /1 下一条

快速回复 返回顶部 返回列表
附近
店铺
微信扫码查看附近店铺
维修
报价
扫码查看手机版报价
信号元
件查询
点位图


芯片搜索

快速回复