前端性能优化成神之路-浏览器缓存机制详解

Posted lo-me

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端性能优化成神之路-浏览器缓存机制详解相关的知识,希望对你有一定的参考价值。

对一个网站而言,CSS、javascript、logo、图标这些静态资源文件更新的频率都比较低,而这些文件又几乎是每次http请求都需要的,如果将这些文件缓存在浏览器中,可以极好的改善性能。

通过设置http头中的cache-control和expires的属性和html Meta标签,可设定浏览器缓存,缓存时间可以是数天,甚至是几个月。

浏览器缓存控制机制有两种:HTML Meta标签 vs. HTTP头信息(主要)

 

HTML Meta 标签定义的缓存机制

可以在HTML页面的<head>节点中加入<meta>标签,代码如下:

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。使用上很简单,但只有部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代理不解析HTML内容本身。

 

 

HTTP头信息缓存机制:

HTTP头信息缓存机制有可以分为两种强缓存(完全不问服务端资源有没有更新,直接拿浏览器缓存)和协商缓存 

强缓存——Expires策略

Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。

不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。

Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。

 

强缓存——Cache-control策略(重点关注):

Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。

只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。(Cache-Control:private, s-maxage=0)值可以是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age

各个消息中的指令含义如下:
Public:指示响应可被任何缓存区缓存。
Private:指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效
no-cache:指示请求或响应消息不能缓存,该选项并不是说可以设置”不缓存“,容易望文生义~ (向服务端发起请求,再看服务端相关的配置比如Last-Modified这样的信息进一步判断浏览器的缓存有没有过期)
no-store:用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存,完全不存下來。
s-maxage: s-maxage优先级高于max-age,只能指定public的缓存
max-age:指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。(表示这个时间内,这个请求都是有效,不会再向服务端发起请求)
min-fresh:指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
max-stale:指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

 

 

协商缓存

Last-Modified/If-Modified-Since:Last-Modified/If-Modified-Since要配合Cache-Control使用。

Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。

If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
 

Etag/If-None-Match:Etag/If-None-Match也要配合Cache-Control使用。

Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。

If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
 
 
 

既生Last-Modified何生Etag

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag(实体标识)呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:

Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间

如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag一起使用时,服务器会优先验证ETag。

yahoo的Yslow法则中则提示谨慎设置Etag:需要注意的是分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败,Yahoo建议分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样,因为除了 last-modified、inode 也很难保持一致)。

Pragma行是为了兼容HTTP1.0,作用与Cache-Control: no-cache是一样的。

最后总结下几种状态码的区别:

技术图片

 

 

用户行为与缓存

浏览器缓存行为还有用户的行为有关,如果大家对 强制刷新(Ctrl + F5) 还有印象的话应该能立刻明白我的意思~技术图片

 

 

以上是关于前端性能优化成神之路-浏览器缓存机制详解的主要内容,如果未能解决你的问题,请参考以下文章

前端性能优化成神之路—前端页面渲染流程

前端性能优化成神之路—浏览器的一个请求从发送到返回都经历了什么

前端性能优化成神之路-HTTP压缩开启gzip

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段

前端技能树,面试复习第 38 天—— 浏览器原理:详解浏览器缓存机制 | 协商缓存与强缓存(重点)

前端浏览器缓存机制