浏览器缓存看这一篇就够了

浏览器缓存作为性能优化的重要一环 , 对于前端而言 , 重要性不言而喻 。以前总是一知半解的 , 所以这次好好整理总结了一下 。
1、缓存机制
首先我们来总体感知一下它的匹配流程 , 如下:

  1. 浏览器发送请求前 , 根据请求头的expires和cache-control判断是否命中(包括是否过期)强缓存策略 , 如果命中 , 直接从缓存获取资源 , 并不会发送请求 。如果没有命中 , 则进入下一步 。
  2. 没有命中强缓存规则 , 浏览器会发送请求 , 根据请求头的last-modified和etag判断是否命中协商缓存 , 如果命中 , 直接从缓存获取资源 。如果没有命中 , 则进入下一步 。
  3. 如果前两步都没有命中 , 则直接从服务端获取资源 。

浏览器缓存看这一篇就够了

文章插图
2、强缓存
强缓存:不会向服务器发送请求 , 直接从缓存中读取资源 。
2.1 强缓存原理
强制缓存就是向浏览器缓存查找该请求结果 , 并根据该结果的缓存规则来决定是否使用该缓存结果的过程 , 强制缓存的情况主要有三种(暂不分析协商缓存过程) , 如下:
  • 第一次请求 , 不存在缓存结果和缓存标识 , 直接向服务器发送请求

浏览器缓存看这一篇就够了

文章插图
  • 存在缓存标识和缓存结果 , 但是已经失效 , 强制缓存是啊比 , 则使用协商缓存(暂不分析)

浏览器缓存看这一篇就够了

文章插图
  • 存在该缓存结果和缓存标识 , 且该结果尚未失效 , 强制缓存生效 , 直接返回该结果

浏览器缓存看这一篇就够了

文章插图
那么强制缓存的缓存规则是什么?
当浏览器向服务器发起请求时 , 服务器会将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器 , 控制强制缓存的字段分别是Expires和Cache-Control , 其中Cache-Control优先级比Expires高 。
2.1.1、 Expires
缓存过期时间 , 用来指定资源到期的时间 , 是服务器端的具体的时间点 。也就是说 , Expires=max-age + 请求时间 , 需要和Last-modified结合使用 。Expires是Web服务器响应消息头字段 , 在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据 , 而无需再次请求 。
Expires 是 HTTP/1 的产物 , 受限于本地时间 , 如果修改了本地时间 , 可能会造成缓存失效 。
2.1.2、 Cache-Control
在HTTP/1.1中 , Cache-Control是最重要的规则 , 主要用于控制网页缓存 , 主要取值为:
  • public:所有内容都将被缓存(客户端和代理服务器都可缓存)
  • private:所有内容只有客户端可以缓存 , Cache-Control的默认取值
  • no-cache:客户端缓存内容 , 但是是否使用缓存则需要经过协商缓存来验证决定
  • no-store:所有内容都不会被缓存 , 即不使用强制缓存 , 也不使用协商缓存
  • max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
需要注意的是 , no-cache这个名字有一点误导 。设置了no-cache之后 , 并不是说浏览器就不再缓存数据 , 只是浏览器在使用缓存数据时 , 需要先确认一下数据是否还跟服务器保持一致 , 也就是协商缓存 。而no-store才表示不会被缓存 , 即不使用强制缓存 , 也不使用协商缓存
2.1.3、设置
强缓存需要服务端设置expires和cache-control 。
Nginx代码参考 , 设置了一年的缓存时间:
 
  1. location ~ .*.(ico|svg|ttf|eot|woff)(.*) {  
  2.   proxy_cache               pnc;  
  3.   proxy_cache_valid         200 304 1y;  
  4.   proxy_cache_valid         any 1m;  
  5.   proxy_cache_lock          on;  


    推荐阅读