当前位置:网站首页>如何设计静态资源缓存方案
如何设计静态资源缓存方案
2022-08-02 06:37:00 【weixin_39805244】
为什么要有缓存
当我们在访问一个页面时,浏览器会先加载HTML文件,然后边解析边加载关联的静态资源,所有资源加载解析完毕后,最终被渲染到屏幕上。
对浏览器来说,用户每次打开页面,都要去请求服务器获取页面资源。如果页面没有更新,每次都去请求服务器是没有必要的。所以,需要有一个缓存功能:把下载的资源先存起来,下次访问页面时直接读取本地数据,从而提高了页面访问速度。
对于服务器来说,需要对每个请求进行解析url,读取文件和返回数据。而服务器的处理能力是有上限的,所以如果能通过缓存减少不必要的请求,将会降低服务器的负载,让它可以做更多有意义的事情。
综上所述,为了提高网页的访问速度,降低服务器的负载,我们需要一个缓存方案,而应用最广的就是http缓存。
http缓存是怎么设计的
1. 过期时间
首先,比较容易想到的方法就是:服务器在返回资源时指定过期时间,浏览器拿到资源后存起来,后续请求如果资源未过期就返回缓存数据,不用再请求服务器了。
这是http1.0的方案,即通过Expires头字段指定过期时间。
Expires: Thu, 05 May 2022 08:13:07 GMT
这里有一个问题:Expires是一个绝对时间,所以要求浏览器和服务器两者的系统时间必需保持同步。
首先,Expires使用的是GMT时间,解决了时区问题。但是,如果浏览器和服务器的系统时间不一致,将会导致浏览器无法准确地判断过期时间。
为了解决这个问题,http1.1使用的是max-age,这是一个相对时间。
cache-control: max-age=60
max-age=60表示资源有效时间为60s,由浏览器自己计算过期时间,自然也就不存在系统时间同步问题了。
当expires和max-age同时存在时,会优先使用max-age。
2. 协商缓存
当浏览器缓存数据过期了,而服务器资源不一定有更新,这时候再去下载一次资源也是没有必要的。此时要和服务器验证资源是否已更新,如果未更新就继续使用缓存,否则再去下载新的资源。这就是http1.1中的协商缓存。
当浏览器缓存数据过期了,要和服务器确认资源是否更新,那么如何判断资源已更新呢?
常见的有以下两种方案:
- 文件内容的hash值。
- 文件最后更新时间。
分别对应http1.1中的协商缓存字段etag/ If-None-Match和last-modified/ If-Modified-Since。
服务器返回资源时会带上字段etag或last-modified。当浏览器缓存过期了,会带上If-None-Match或If-Modified-Since字段请求服务器验证资源是否更新。服务器判断资源有更新,就返回200和新资源;否则返回304。
有了协商缓存,就能在浏览器缓存过期了,而服务器资源实际未更新的情况下避免重复下载。
当etag和last-modified同时存在时,浏览器会优先选择etag。相对而言,etag精度更高:etag只在文件内容变化时更新,而last-modified更新时不一定代表文件内容有更新。
过期时间和协商缓存是http缓存的核心内容。除此之外,cache-control还提供了其它指令,可以满足多种应用场景。
应用场景
PS:当我们刷新页面或第二次在地址栏按回车键,都会直接请求服务器。为了验证本地缓存未过期的情况,需要打开新的tab访问页面。
1. 缓存静态资源
Cache-Control:max-age=31536000
应用场景:一般用来缓存更新频率低的资源。
像js/css/img可以设置一年,当文件需要及时更新时,只需要更改html中引用的文件名。(所以html一般需要保持较高的新鲜度)
示例:
第一次请求:返回200,max-age=31536000 和 Last-Modified/ETag。
# request
GET /script.js HTTP/1.1
# response
HTTP/1.1 200 OK
Content-Type: application/javascript
Last-Modified: Fri, 03 Jun 2022 08:24:43 GMT
ETag: "6299c54b-24"
Cache-Control: max-age=31536000
第二次请求:返回200,显示数据来自缓存。
# request
GET /script.js HTTP/1.1
# response
HTTP/1.1 200 OK
Content-Type: application/javascript
Last-Modified: Fri, 03 Jun 2022 08:24:43 GMT
ETag: "6299c54b-24"
Cache-Control: max-age=31536000
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8yI9E4D9-1659171954471)(C:\Users\Ys\AppData\Roaming\Typora\typora-user-images\image-20220604110638294.png)]
2. 强制协商缓存
浏览器在使用缓存之前必需跟原始服务器协商验证。
# 方法一
Cache-Control: no-cache
# 方法二
Cache-Control: max-age=0, must-revalidate
适用场景: 对数据实时性要求高,又能用缓存提高访问速度。
一般的html使用协商缓存保证实时性,对于并发量大的页面也可以设置较短的缓存有效时间。
为什么html页面实时性要求高呢?
如果html没有及时更新,将会导致页面引用的js/css等资源(缓存时间较长)无法及时更新。另外,如果涉及接口变更,前后端必须同步更新的情况,那么访问旧的html将会导致接口报错。
示例:
第一次请求:返回200和Last-Modified/ETag。
# request
GET /index.html HTTP/1.1
Cache-Control: max-age=0
# response
HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Fri, 03 Jun 2022 07:32:28 GMT
ETag: "6299b90c-14f"
Cache-Control: no-cache
第二次请求:请求带上Last-Modified/ETag,服务器验证资源未更新,返回304。
# request
GET /index.html HTTP/1.1
If-None-Match: "6299b90c-14f"
If-Modified-Since: Fri, 03 Jun 2022 07:32:28 GMT
# response
HTTP/1.1 304 Not Modified
Last-Modified: Fri, 03 Jun 2022 07:32:28 GMT
ETag: "6299b90c-14f"
Cache-Control: no-cache
3. 禁止缓存
禁止浏览器缓存资源(响应)和不使用缓存(请求)。
Cache-Control: no-store
适用场景:包含敏感信息等不希望缓存的场景。
示例:
第一次请求:返回200和no-store。
# request
GET /index.html HTTP/1.1
Cache-Control: max-age=0
# response
HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Fri, 03 Jun 2022 08:25:15 GMT
ETag: "6299c56b-178"
Cache-Control: no-store
第二次请求:请求服务器,返回200和新资源。
4. 代理服务器缓存控制
Cache-Control:public,max-age=600,s-maxage=60
public表示浏览器和代理服务器都可以缓存资源;private只有浏览器可以缓存资源;s-maxage表示代理服务器缓存的有效时间。
http缓存除了存在浏览器(私有缓存),还可以存在代理服务器(公共缓存)。例如常见的CDN,即降低了网络延迟,还能降低服务器的负载。
对于安全性要求高的资源,建议设置为Cache-Control:private,即禁用公共缓存。因为数据一旦被代理服务器缓存下来,就多了一份被攻击的风险。
各大网站缓存方案
B站
- html:no-cache
- JS文件:max-age=31536000(1年),文件命名带版本号或指纹信息,方便及时更新。
- CSS文件:max-age=31536000,文件命名带版本号或指纹信息,方便及时更新。
- 图片:max-age=31536000,文件命名带版本号或指纹信息,方便及时更新。
- XHR请求: no-cache
微信
html:public, max-age=500
JS文件:max-age=31536000(1年),文件命名带版本号或指纹信息,方便及时更新。
CSS文件:max-age=31536000,文件命名带版本号或指纹信息,方便及时更新。
图片:max-age=31536000,文件命名带版本号或指纹信息,方便及时更新。
XHR请求:no-cache,must-revalidate
淘宝
- html:默认
- js文件:max-age=2592000(一个月),s-maxage=86400;文件命名带版本号或指纹信息,方便及时更新。
- CSS文件:max-age=2592000,s-maxage=3600;文件命名带版本号或指纹信息,方便及时更新。
- 图片:max-age=15552000;文件命名带版本号或指纹信息,方便及时更新。
新浪
- html: max-age=60
- js文件:max-age=31536000;max-age=14400;max-age=3600
- CSS文件:public, max-age=14400
- 图片:max-age=31536000(一年)
实现方式
1. HTML缓存
通过 meta标签 的http-equiv和content来设置报文头:Cache-Control和Expires。
<meta http-equiv="Expires" content="Mon, 20 Jul 2013 23:00:00 GMT" />
<meta http-equiv="Cache-Control" content="max-age=7200" />
用meta标签的http-equiv属性来设置强缓存。用法简单,不需要服务器支持。适合更新频率低的页面。
2. nginx缓存
当nginx作为静态资源服务器时,通过配置http头保证浏览器缓存行为一致。
# html使用协商缓存
location ~.*\.html$
{
add_header Cache-Control no-cache;
# 作用跟Cache-Control no-cache一致;兼容HTTP/1.0
add_header Pragma no-cache;
}
# 对于更新频率低的,缓存有效时间可设置长一点。
location ~.*\.(js|css|png|jpg)$
{
expires 365d;
}
3. webpack文件名hash
entry:{
main: path.join(__dirname,'./main.js'),
vendor: ['react', 'antd']
},
output:{
path:path.join(__dirname,'./dist'),
publicPath: '/dist/',
filname: 'bundle.[contenthash].js'
}
通过webpack打包,自动给文件名加上hash值。其中,contenthash表示hash值由文件内容计算得到,内容不同产生的contenthash值也不一样。
总结
为了提高网页的访问速度,降低服务器的负载,我们需要一个缓存方案,而应用最广的就是http缓存。
http缓存的核心是过期时间和协商缓存:服务器在返回资源时指定过期时间,浏览器拿到资源后存起来,后续请求如果资源未过期就返回缓存数据,不用再请求服务器了;当浏览器缓存过期后,再和服务器协商确认资源是否更新,如果更新则返回新资源,否则返回304。
基于http缓存,我们可以实现对静态资源的缓存控制,从而提升网站性能。通常会把js和css等更新频率低的资源设置较长的过期时间,把html等实时性要求高的资源设置为不缓存或者强制协商缓存。
最后,列举了各大网站的缓存方案可供借鉴,介绍了通过html和nginx等方式来实现缓存配置。
参考资料
边栏推荐
- 张驰课堂:六西格玛测量系统的误差分析与判定
- jvm 二之 栈帧内部结构
- Ue after video tutorial first
- 解决Pytorch模型在Gunicorn部署无法运行或者超时问题
- [Dataset][VOC] Male and female dataset voc format 6188 sheets
- pointer arithmetic in c language
- 堡垒机、堡垒机的原理
- Specified URL is not reachable,caused by :‘Read timed out
- 【故障诊断分析】基于matlab FFT轴承故障诊断(包络谱)【含Matlab源码 2002期】
- optional
猜你喜欢

Wuhan 2022 organizing of the high-performance computing added new ecological development of high-performance computing

PMP新考纲考试内容介绍

The second day HCIP

张驰咨询:企业实施精益管理的最大障碍,只把精益作为一种工具和方法

第06章 索引的数据结构【2.索引及调优篇】【MySQL高级】

看图就懂|衡量业务增长健康的销售指标如何选择

论文《Deep Multifaceted Transformers for Multi-objective Ranking in Large-Scale E-commerce Recommender》

【npm install 报错问题合集】- npm ERR! code ENOTEMPTY npm ERR! syscall rmdir

PWA 踩坑 - 第一次加载页面后无法获取CacheStorage某些资源

宝塔+FastAdmin 404 Not Found
随机推荐
打卡day05
关于ue4.27像素流送打包后的本地服务器问题
(Notes are not completed) [Graph Theory] Traversal of graphs
PMP新考纲考试内容介绍
项目开发规范
队列题目:无法吃午餐的学生数量
Kind of weird!Access the destination URL, the host can container but not
【图像去噪】基于matlab双立方插值和稀疏表示图像去噪【含Matlab源码 2009期】
Facebook社媒营销的5大技巧,迅速提高独立站转化率!
optional
Ue after video tutorial first
About the local server problem after ue4.27 pixel streaming package
docker 安装mysql
张驰咨询:企业实施精益管理的最大障碍,只把精益作为一种工具和方法
宝塔+FastAdmin 404 Not Found
optional
【CNN回归预测】基于matlab卷积神经网络CNN数据回归预测【含Matlab源码 2003期】
两篇不错的php debug教程
2022.07.31(LC_6132_使数组中所有元素都等于零)
PWA 踩坑 - 第一次加载页面后无法获取CacheStorage某些资源