We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
深入理解浏览器的缓存机制
跟着这篇文章整理的
install
fetch
内存中的缓存。
<link rel="prefetch">
硬盘中的缓存。
关于哪些文件会缓存在内存、哪些在硬盘中:
浏览器根据请求资源时返回的响应头来判断资源是否该缓存; 根据请求头与响应头判断如何使用缓存。
不会发起请求,直接从缓存中读取资源,在 Devtool 中可以看到资源请求返回 200 状态码, Size 显示 from disk cache 或 from memory cache
通过设置 Expires 和 Cache-Control 两个 header 实现
Expires
Cache-Control
指令:
Expires 与 Cache-Control 区别在于,前者是 HTTP/1.0 的产物,二者同时存在时, Cache-Control 优先级更高。在不支持 HTTP/1.1 的环境下则 Expires 有效。现阶段 Expires 只是一种兼容的写法。
强缓存是基于时间来判断是否使用缓存,而不关心服务端文件是否已经更新,这可能导致拿不到最新的文件。
在强缓存失效后,就会使用协商缓存; 协商缓存会发起请求,由服务器根据缓存标识决定是否使用缓存; 如果协商缓存有效,则响应 304 状态码, Not Modified 并且不会发送资源,否则会返回 200 状态码与请求资源结果。
协商缓存可以通过两对 headers 实现:
Last-Modified 记录文件在服务器上的最后修改时间,当浏览器请求这个文件时,会带上 Last-Modified 请求头。
当浏览器下次请求这个资源时,如果有 Last-Modified 请求头,则会添加 If-Modified-Since ,值为 Last-Modified 的值。
当服务器收到请求时,会将浏览器发送的 If-Modified-Since 值与请求资源的最后修改时间进行对比,如果没有变化,则返回 304 使用缓存;如果小于服务器中这个资源的最后修改时间,则表示文件有更新,返回新的资源和 200 。
缺陷:
ETag 是服务端返回的当前资源的唯一标识(服务端生成),只要资源有变化,则 ETag 会重新生成。
浏览器下次请求缓存文件时,会把上一次的 ETag 放入 If-None-Match 中,服务端接收到请求后,会对比 If-None-Match 与服务器上文件的 ETag ,来判断该资源是否有更新。
ETag 的优势在于精确度高于以秒为精度的 Last-Modified
其缺点则是服务端要计算 hash 要耗费性能
在优先级上,服务器优先考虑 ETag
没有一个绝对通用的缓存策略,只有根据不同的场景来使用不同的策略才能发挥缓存的作用。
对于频繁变动的资源,使用 Cache-Control: no-cache ,这样,浏览器每次请求此类资源都会发起请求,配合 ETag 或 Last-Modified 来验证缓存资源是否有效。
Cache-Control: no-cache
此做法不能节省请求,但可以减少响应数据的大小。
对于这类资源通常使用 Cache-Control: max-age=31536000 ,配置一个较大的 max-age ,这样浏览器会使用强缓存,而不会发起请求。
Cache-Control: max-age=31536000
如果遇到文件更新,则通过改变文件名的方式更新,旧的资源则因 URL 不同,不会再被请求而弃用。
这个场景在平时用得比较多,例如线上引用的 JS、CSS 等资源,在文件名后面都会加上一个 hash 值。
这部分与浏览器或许不是很相关
衡量缓存是否有效的重要指标
命中率=返回正确结果数/请求缓存次数
能存放缓存的最大个数,超过这个数量,则会触发清空策略
合理设置最大元素值可提高缓存的命中率
一些简单的策略:
The text was updated successfully, but these errors were encountered:
No branches or pull requests
思维导图
深入理解浏览器的缓存机制
跟着这篇文章整理的
缓存位置
1. Service Worker
install
事件中缓存文件fetch
事件中拦截网络请求,判断是否命中缓存fetch
函数2. Memory Cache
内存中的缓存。
<link rel="prefetch">
3. Disk Cache
硬盘中的缓存。
关于哪些文件会缓存在内存、哪些在硬盘中:
4. Push Cache
缓存类型
浏览器根据请求资源时返回的响应头来判断资源是否该缓存;
根据请求头与响应头判断如何使用缓存。
1. 强缓存
不会发起请求,直接从缓存中读取资源,在 Devtool 中可以看到资源请求返回 200 状态码, Size 显示 from disk cache 或 from memory cache
通过设置
Expires
和Cache-Control
两个 header 实现Expires
Cache-Control
指令:
两者对比
Expires 与 Cache-Control 区别在于,前者是 HTTP/1.0 的产物,二者同时存在时, Cache-Control 优先级更高。在不支持 HTTP/1.1 的环境下则 Expires 有效。现阶段 Expires 只是一种兼容的写法。
强缓存是基于时间来判断是否使用缓存,而不关心服务端文件是否已经更新,这可能导致拿不到最新的文件。
2. 协商缓存
在强缓存失效后,就会使用协商缓存;
协商缓存会发起请求,由服务器根据缓存标识决定是否使用缓存;
如果协商缓存有效,则响应 304 状态码, Not Modified 并且不会发送资源,否则会返回 200 状态码与请求资源结果。
协商缓存可以通过两对 headers 实现:
Last-Modified 和 If-Modified-Since
Last-Modified 记录文件在服务器上的最后修改时间,当浏览器请求这个文件时,会带上 Last-Modified 请求头。
当浏览器下次请求这个资源时,如果有 Last-Modified 请求头,则会添加 If-Modified-Since ,值为 Last-Modified 的值。
当服务器收到请求时,会将浏览器发送的 If-Modified-Since 值与请求资源的最后修改时间进行对比,如果没有变化,则返回 304 使用缓存;如果小于服务器中这个资源的最后修改时间,则表示文件有更新,返回新的资源和 200 。
缺陷:
ETag 和 If-None-Match
ETag 是服务端返回的当前资源的唯一标识(服务端生成),只要资源有变化,则 ETag 会重新生成。
浏览器下次请求缓存文件时,会把上一次的 ETag 放入 If-None-Match 中,服务端接收到请求后,会对比 If-None-Match 与服务器上文件的 ETag ,来判断该资源是否有更新。
ETag 的优势在于精确度高于以秒为精度的 Last-Modified
其缺点则是服务端要计算 hash 要耗费性能
在优先级上,服务器优先考虑 ETag
应用场景
没有一个绝对通用的缓存策略,只有根据不同的场景来使用不同的策略才能发挥缓存的作用。
1. 频繁变动的资源
对于频繁变动的资源,使用
Cache-Control: no-cache
,这样,浏览器每次请求此类资源都会发起请求,配合 ETag 或 Last-Modified 来验证缓存资源是否有效。此做法不能节省请求,但可以减少响应数据的大小。
2. 不常变化的资源
对于这类资源通常使用
Cache-Control: max-age=31536000
,配置一个较大的 max-age ,这样浏览器会使用强缓存,而不会发起请求。如果遇到文件更新,则通过改变文件名的方式更新,旧的资源则因 URL 不同,不会再被请求而弃用。
这个场景在平时用得比较多,例如线上引用的 JS、CSS 等资源,在文件名后面都会加上一个 hash 值。
用户触发缓存行为
Cache-Control: no-cache
关于缓存的其他知识
这部分与浏览器或许不是很相关
缓存的特征
1. 命中率
衡量缓存是否有效的重要指标
2. 最大元素
能存放缓存的最大个数,超过这个数量,则会触发清空策略
合理设置最大元素值可提高缓存的命中率
3. 清空策略
一些简单的策略:
参考
The text was updated successfully, but these errors were encountered: