推荐阅读:css
有时,当第二次访问网站时,看起来比较怪,样式不正常。web
一般,是由于 cache control 缓存控制策略定义不正确,致使服务端最新部署以后客户端没有接收到最新的更改。算法
本文将向您展现正确的缓存设置,以便在每次部署后使全部用户的网站保持最新状态。后端
浏览器为了提升性能,向服务器请求资源时,都尽可能多从本地缓存获取,尽可能少从服务器获取。浏览器
具体行为咱们能够经过指令来控制,经过设置 HTTP 响应头来实现。缓存
缓存处理相关的最经常使用指令包括:服务器
若是没有设置缓存控制指令,浏览器将从服务器获取每一个资源,这会增长页面的加载时间。架构
没有缓存设置的请求流程:并发
由浏览器决定如何在没有服务器指示的状况下缓存信息。app
不一样浏览器策略不一样,例如 Chrome 和 Safari 每次都从后端下载数据。
为了清楚地定义缓存的处理方式,让咱们深刻了解一下缓存控制指令。
Etag 可让咱们在不用下载资源的状况下,就知道服务器上的资源是否变动了。
服务器在给浏览器发送资源文件时(例如 css 文件),会对此资源内容计算出一个 hash 值,做为此文件的 tag,一块儿发送给浏览器。
浏览器下次请求此资源文件时,先把这个 tag 发给服务器,HTTP header 信息例如:
If-None-Match: W/“1d2e7–1648e509289”
服务器和本地文件的 hash 值对比。
若是同样,就告诉浏览器没有变化,可使用缓存文件,不然浏览器下载新文件。
使用Etag请求流-第一次加载:
使用Etag请求流-第二次加载:
启用 Etag 缓存策略后,咱们老是会去服务器检查文件的哈希值,而后浏览器才会决定从缓存中提取文件或将其彻底加载。
若是未修改,则不管您要请求的是10KB仍是10MB的文件,只需80–100字节便可进行验证。
服务器有每一个文件的最后修改时间戳,在第一次文件加载以后,客户端会向服务器询问此文件在某时间以后是否更改过。
HTTP header 信息例如:
If-Modified-Since: Fri, 13 Jul 2018 10:49:23 GMT
若是改了,就下载新文件,不然使用缓存。
看着挺好,但现实状况并不必定是这样的,“Last-Modified” 是一个弱缓存头信息,浏览器有本身的缓存策略,会自行决定是否从缓存中获取资源或下载新文件,不一样浏览器处理方式也不同。
使用 Last-Modified 的请求流程 - 第一次加载:
使用 Last-Modified 的请求流程 - 第二次加载(完美状况):
使用 Last-Modified 的请求流程 - 第二次加载(一般状况):
因此,“Last-Modified” 是不可靠的,我宁愿彻底不使用他。
这个指令告诉浏览器此文件在本地缓存多长时间。
以秒为单位,形式为:
Cache-Control: max-age=31536000
使用此策略后,浏览器彻底不用向服务器发起请求了,直接使用本地缓存,很是快。
可是,没有办法确保这段时间内服务器中的文件不会修改。
所以,为了让浏览器下载最新的文件,咱们可使用一些构建工具,例如 Webpack、Gulp。
每一个文件都在服务器中进行预编译,对文件内容进行 hash 计算,把 hash 值添加到文件名中,例如 “app-72420c47cc.css”。
这样,文件内容的变化就能够反应在文件名上,对浏览器来说就是一个新的文件,旧文件的缓存也就没有了,会从服务器上获取新的。
这个方法适用于 CSS JS 和图片文件。
no-cache(无缓存)不意味着根本没有缓存,它只是告诉浏览器在使用缓存以前先验证服务器上的资源。
须要与 Etag 一块儿使用,所以浏览器将发送一个简单请求并加载额外的80个字节以验证文件的状态。
对于 HTML 文件,就须要使用 “no-cache”。
使用 Gulp,Webpack 这类工具将惟一的哈希值添加到 css,js 和图像文件(如app-67ce7f3483.css)。
对于 js,css 和图像文件,设置 Cache-Control:public,max-age = 31536000,不设置 Etag 和 Last-Modified。
对于 HTML 文件,设置 Cache-Control: no-cache 和 Etag。
翻译整理自:
https://medium.com/pixelpoint...