如何定义最佳 Cache-Control 策略
定义最佳 Cache-Control 策略
按照以上决策树为您的应用使用的特定资源或一组资源确定最佳缓存策略。在理想的情况下,您的目标应该是在客户端上缓存尽可能多的响应,缓存尽可能长的时间,并且为每个响应提供验证令牌,以实现高效的重新验证。
Cache-Control 指令和说明 | |
---|---|
max-age=86400 | 浏览器以及任何中间缓存均可将响应(如果是“public”响应)缓存长达 1 天(60 秒 x 60 分钟 x 24 小时)。 |
private, max-age=600 | 客户端的浏览器只能将响应缓存最长 10 分钟(60 秒 x 10 分钟)。 |
no-store | 不允许缓存响应,每次请求都必须完整获取。 |
根据 HTTP Archive,在排名最高的 300,000 个网站(按照 Alexa 排名)中,所有下载响应中有半数可由浏览器缓存,这可以大量减少重复的网页浏览和访问。当然,这并不意味着您的特定应用有 50% 的资源可以缓存。一些网站的资源 90% 以上都可以缓存,而其他网站可能有许多私密或时效要求高的数据根本无法缓存。
废弃和更新缓存的响应
- 在资源“过期”之前,将一直使用本地缓存的响应。
- 您可以通过在网址中嵌入文件内容指纹,强制客户端更新到新版本的响应。
- 为获得最佳性能,每个应用都需要定义自己的缓存层次结构。
浏览器发出的所有 HTTP 请求会首先路由到浏览器缓存,以确认是否缓存了可用于满足请求的有效响应。如果有匹配的响应,则从缓存中读取响应,这样就避免了网络延迟和传送产生的流量费用。
不过,如果您想更新或废弃缓存的响应,该怎么办?例如,假定您已告诉访问者将某个 CSS 样式表缓存长达 24 小时 (max-age=86400),但设计人员刚刚提交了一个您希望所有用户都能使用的更新。您该如何通知拥有现在“已过时”的 CSS 缓存副本的所有访问者更新其缓存?在不更改资源网址的情况下,您做不到。
浏览器缓存响应后,缓存的版本将一直使用到过期(由 max-age 或 expires 决定),或一直使用到由于某种其他原因从缓存中删除,例如用户清除了浏览器缓存。因此,构建网页时,不同的用户可能最终使用的是文件的不同版本;刚获取了资源的用户将使用新版本的响应,而缓存了早期(但仍有效)副本的用户将使用旧版本的响应。
所以,如何才能鱼和熊掌兼得:客户端缓存和快速更新?您可以在资源内容发生变化时更改它的网址,强制用户下载新响应。通常情况下,可以通过在文件名中嵌入文件的指纹或版本号来实现 - 例如 style.x234dff.css。
因为能够定义每个资源的缓存策略,所以您可以定义“缓存层次结构”,这样不但可以控制每个响应的缓存时间,还可以控制访问者看到新版本的速度。为了进行说明,我们一起分析一下上面的示例:
- HTML 被标记为“no-cache”,这意味着浏览器在每次请求时都始终会重新验证文档,并在内容变化时获取最新版本。此外,在 HTML 标记内,您在 CSS 和 JavaScript 资产的网址中嵌入指纹:如果这些文件的内容发生变化,网页的 HTML 也会随之改变,并会下载 HTML 响应的新副本。
- 允许浏览器和中间缓存(例如 CDN)缓存 CSS,并将 CSS 设置为 1 年后到期。请注意,您可以放心地使用 1 年的“远期过期”,因为您在文件名中嵌入了文件的指纹:CSS 更新时网址也会随之变化。
- JavaScript 同样设置为 1 年后到期,但标记为 private,这或许是因为它包含的某些用户私人数据是 CDN 不应缓存的。
- 图像缓存时不包含版本或唯一指纹,并设置为 1 天后到期。
您可以组合使用 ETag、Cache-Control 和唯一网址来实现一举多得:较长的过期时间、控制可以缓存响应的位置以及随需更新。
缓存检查清单
不存在什么最佳缓存策略。您需要根据通信模式、提供的数据类型以及应用特定的数据更新要求,为每个资源定义和配置合适的设置,以及整体的“缓存层次结构”。
在制定缓存策略时,您需要牢记下面这些技巧和方法:
- 使用一致的网址:如果您在不同的网址上提供相同的内容,将会多次获取和存储这些内容。提示:请注意,网址区分大小写。
- 确保服务器提供验证令牌 (ETag):有了验证令牌,当服务器上的资源未发生变化时,就不需要传送相同的字节。
- 确定中间缓存可以缓存哪些资源:对所有用户的响应完全相同的资源非常适合由 CDN 以及其他中间缓存进行缓存。
- 为每个资源确定最佳缓存周期:不同的资源可能有不同的更新要求。为每个资源审核并确定合适的 max-age。
- 确定最适合您的网站的缓存层次结构:您可以通过为 HTML 文档组合使用包含内容指纹的资源网址和短时间或 no-cache 周期,来控制客户端获取更新的速度。
- 最大限度减少搅动:某些资源的更新比其他资源频繁。如果资源的特定部分(例如 JavaScript 函数或 CSS 样式集)会经常更新,可以考虑将其代码作为单独的文件提供。这样一来,每次获取更新时,其余内容(例如变化不是很频繁的内容库代码)可以从缓存获取,从而最大限度减少下载的内容大小。
如何定义最佳 Cache-Control 策略的更多相关文章
- 网站 cache control 最佳实践
推荐阅读: 2020年软件开发趋势 高并发案例 - 库存超发问题 负载均衡的分类及算法 异地多活架构 Postman 的替代品来了 有时,当第二次访问网站时,看起来比较怪,样式不正常. 通常,是因为 ...
- cache写策略
cache写策略 Write Through (完全写入) CPU向cache写入数据时,同时向memory也写一份,使cache和memory的数据保持一致.优点是简单,缺点是每次都要访问memor ...
- [转]ASP.NET Core: Static Files cache control using HTTP Headers
本文转自:https://www.ryadel.com/en/asp-net-core-static-files-cache-control-using-http-headers/ Every sea ...
- Mybatis Cache 缓存策略
Mybatis Cache 缓存策略 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用 ...
- 验证Kubernetes YAML的最佳实践和策略
本文来自Rancher Labs Kubernetes工作负载最常见的定义是YAML格式的文件.使用YAML所面临的挑战之一是,它相当难以表达manifest文件之间的约束或关系. 如果你想检查所有部 ...
- Kubernetes YAML最佳实践和策略
Kubernetes工作负载最常用YAML格式的文件来定义. YAML的问题之一就是很难描述清单文件之间的约束或关系. 如果你希望检查是否已从受信任的注册表中提取部署到群集中的所有映像,该怎么办? 如 ...
- 转:深入浅出cache写策略
转自:http://www.ssdfans.com www.ssdfans.com › blog › 2018/07/27 › 深入浅出cach... 随着计算机行业的飞速发展,CPU的速度和内存的大 ...
- Cache写策略(Cache一致性问题与骚操作)
写命中 写直达(Write Through) 信息会被同时写到cache的块和主存中.这样做虽然比较慢,但缺少代价小,不需要把整个块都写回主存.也不会发生一致性问题. 对于写直达,多出来%10向主存写 ...
- java cache过期策略两种实现,一个基于list轮询一个基于timer定时
最近项目要引入缓存机制,但是不想引入分布式的缓存框架,所以自己就写了一个轻量级的缓存实现,有两个版本,一个是通过timer实现其超时过期处理,另外一个是通过list轮询. 首先要了解下ja ...
随机推荐
- 创建分区swap分区
1.将文件系统卸载 #umount /sdc5 2.创建swap分区 #mkswap /dev/sdc5 3.激活swap分区 #swapon -a /dev/sdc5 4.查看swap分区情况 #s ...
- 基本控件文档-UILabel属性
CHENYILONG Blog 基本控件文档-UILabel属性 Fullscreen UILabel属性技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http ...
- laravel二维数组手动分页显示
示例:数组 $user 如下 $user: array (size=) 'sort' => array (size=) => float 0.028616622341171 => f ...
- 【leetcode 简单】 第一百四十六题 最长和谐子序列
和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1. 现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度. 示例 1: 输入: [1,3,2,2,5,2,3,7] ...
- 【leetcode 简单】 第六十八题 二叉搜索树的最近公共祖先
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先. 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p.q,最近公共祖先表示为一个结点 x,满足 x 是 p.q 的祖先且 x ...
- 在JS数组指定位置插入元素
很多与数组有关的任务听起来很简单,但实际情况并不总是如此,而开发人员在很多时候也用不到他.最近我碰到了这样一个需求: 将一个元素插入到现有数组的特定索引处.听起来很容易和常见,但需要一点时间来研究它. ...
- 2016.5.19——Excel Sheet Column Title
Excel Sheet Column Title 本题收获: 1.由int型转换为整型(string),如何转化, res = 'A'+(n-1)%26和之前由A-z转化为十进制相反,res = s[ ...
- aarch64_o1
OCE-devel-0.18.1-1.fc26.aarch64.rpm 2017-05-16 03:37 5.4M fedora Mirroring Project OCE-draw-0.18.1-1 ...
- OpenStack 监控解决方案
正如你们看到的那样,到目前为止(OpenStack Kilo),OpenStack自己的监控组件Telemetry并不是完美, 获取的监控数据以及制作出来的图表有时候让人匪夷所思,因其重点并不是监控而 ...
- java 一个函数如何返回多个值
在开发过程中,经常会有这种情况,就是一个函数需要返回多个值,这是一个问题!! 网上这个问题的解决方法: 1.使用map返回值:这个方法问题是,你并不知道如何返回值的key是什么,只能通过doc或者通过 ...