本帖最后由 Qter 于 2021-9-23 14:32 编辑
https://blog.csdn.net/chuanglan/article/details/103357375
http://www.rrdaj.com/hzseo/yi-dong-duan-seo/3064.html
在本文中,我们将解释浏览器如何使用其缓存(包括 memory cache vs disk cache)更快地加载页面,哪些因素决定缓存持续时间,以及我们如何在必要时绕过缓存。为什么缓存很重要?这个我就不多说了,大家可以去搜下,看看我写的其他缓存类的文章即可!浏览器缓存的工作原理就是–用户从未访问过到再次访问你的网站的过程中,浏览器将从Web服务器检索HTML页面,然后查询其静态资源(JavaScript,CSS,图像)的缓存。
浏览器到底到底是怎么知道在缓存什么呢?目前主流的浏览器缓存分为两类–强缓存和协商缓存
一、协商缓存
浏览器检查Web服务器生成的HTTP响应的标头,一般用于缓存的标题有四个:
- ETag
- Cache-Control
- Expires
- Last-Modified
一、ETag
ETag是作为一个缓存验证令牌的字符串,这通常是文件内容的hash值。服务器可以在其响应中包括ETag,然后浏览器可以在请求中使用它(在文件过期之后),以便确定缓存是否包含过时的副本。如果hash相同,则资源未更改,服务器就以304状态码(未修改)来响应空主体,也就是说浏览器知道使用缓存副本仍然是可行的。不过要注意的是,ETag仅在文件从缓存过期时用于请求。
二、Cache-Control
所述Cache-Control头部具有一个数目,我们可以设置它的 Cache Behavior,Expiration 和 Validation,当然这些也可以组合在一起。
Cache Behavior如下: 1、Cache-Control: public public表示资源可以被浏览器,CDN等缓存 2、Cache-Control: private private表示资源只能由浏览器缓存 3、Cache-Control: no-store 这就告诉浏览器始终从服务器请求资源 4、Cache-Control: no-cache
这告诉浏览器缓存文件但不使用它,直到它检查服务器以验证我们有最新版本,主要使用ETag标头完成此验证。它通常与HTML文件一起使用,因为浏览器始终需要检查最新标记是有可用的。
三、Expires
1、Cache-Control: max-age=60 这指定了资源应该被缓存的时间长度(以秒为单位),也就是说它应该被缓存1分钟,建议最大值不应超过1年(max-age = 31536000)。 Cache-Control:s-max-age = 60 这仅适用于像CDN这样的中间缓存。 2、Validation (验证) Cache-Control: must-revalidate 这表示必须在使用之前验证老旧的资源状态再缓存它,并且不应使用过期资源。 3、Expires(过期) 该过期头部信息是 HTTP 1.0,现在仍然在许多网站使用。此标头字段提供过期日期,在该日期之后就被视为无效了。 比如:Expires: Wed, 25 Jul 2018 21:00:00 GMT,如果Cache-Control中有max-age指令,浏览器将忽略此字段。
四、Last-Modified
这个标头也来自HTTP 1.0,比如: Last-Modified: Mon, 12 Dec 2016 14:45:00 GMT 此字段说明上次修改资源的日期和时间。
HTTP缓存响应如下: - Accept-Ranges: bytes
- Cache-Control: max-age=3600
- Connection: Keep-Alive
- Content-Length: 4361
- Content-Type: image/png
- Date: Tue, 25 Jul 2017 17:26:16 GMT
- ETag: "1109-554221c5c8540"
- Expires: Tue, 25 Jul 2017 18:26:16 GMT
- Keep-Alive: timeout=5, max=93
- Last-Modified: Wed, 12 Jul 2017 17:26:05 GMT
信息解读: 服务器使用的是: Apache
第2行告诉我们max-age是1小时
第5行告诉我们这是一张PNG图片
第7行向我们表达了ETag值,该值将在1小时标记后用于验证,以验证资源是否未更改
第8行是Expires标题,因为设置了max-age,它将被忽略
第10行是Last-Modified标题,显示上次修改图片的时间
缓存的会出现的问题 通过以上,我们已经知道浏览器缓存是非常棒的,我们应该多多利用它。但我们也希望用户在进行更新时能够看到我们页面的最新版本,我们不能指望他们每次访问我们的网站都得刷新,那不累死了,这类问题也是开发人员和用户经常遇到的。比如用户可能在浏览器中缓存了一些旧的 JavaScript,导致表单重置,而不是在点击“登录”按钮时提交。
假设我们在名为app.min.js的JavaScript文件中修复了一个 bug,并更新推送到我们的网站。 比如HTML看起来像: <script src=”assets/js/app.min.js”> 假如我们的Web服务器将JavaScript文件的max-age设置为1周(604,800秒)则: Cache-Control: private, max-age=604800
更新后,一些用户反映他们仍然有问题bug。怎么回事呢?原来是第一个用户在2周前访问了该网站,并有一个缓存app.min.js的缓存副本。由于副本早于max-age,浏览器从服务器检索文件,并获得最新的版本。另一个用户在2天前就访问了该网站,并且还有一个缓存app.min.js的缓存副本,这个副本比 max-age 更新,所以他的浏览器仍然很可以使用缓存副本。具体怎么解决,大家可以在我博客搜下相关文章查看!
二、强缓存:
disk cache(磁盘缓存) 和 memory cache(内存缓存)的区别?
它们也属于强缓存的一种,现在浏览器缓存存储图像和网页等(主要在磁盘上),而你的操作系统缓存文件可能大部分在内存缓存中。使用这两个缓存功能,是因为它比从远程的 web 服务器获取这些资源的方式更近、更快。Cpu 本身是有”缓存线”的,它是程序最近使用的内存(RAM)部分的副本。这样,如果一个程序在一个循环中运行(一遍又一遍地做同样的事情) ,它也就不必为每个指令或数据块进入 RAM 了。这个缓存比 RAM 快得多,但是它非常小,因为超快的内存毕竟昂贵。
强缓存作为性能优化中缓存方面最有效的手段,能够极大的提升性能。由于强缓存不会向服务端发送请求,对服务端的压力也是大大减小。对于不太经常变更的资源,可以设置一个超长时间的缓存时间,比如一年。浏览器在首次加载后,都会从缓存中读取。但是由于不会向服务端发送请求,那么如果资源有更改的时候,怎么让浏览器知道呢?现在常用的解决方法是加一个?v=xxx的后缀,在更新静态资源版本的时候,更新这个v的值,这样相当于向服务端发起一个新的请求,从而达到更新静态资源的目的。
至于区别主要在于提取速度上,memory cache 要比 disk cache 快的多,怎么使用要看前端技术人员结合自己网站来选择了,两个都是很不错的缓存方式!举个例子:从远程 web 服务器直接提取访问文件可能需要500毫秒(半秒),那么磁盘访问可能需要10-20毫秒,而内存访问只需要100纳秒,更高级的还有 L1缓存访问(最快和最小的 CPU 缓存)只需要0.5纳秒。
|