【性能优化】强制缓存|协商缓存–实用知识

  • Post author:
  • Post category:其他




🌻 前言

前几天我工作比较闲,就想着看看我司的前端项目有什么可以性能优化的点。于是乎在一个h5项目里,发现没有配置缓存策略。我找到架构组的同学,说明了这个问题。

因为此项目是部署在腾讯云服务器上的,在腾讯云管理后台支持配置缓存策略。

配置缓存策略后,平均每个页面FP缩小了有200ms(因为这个h5项目采用的是gulp工作流,几乎每个页面都是单页面,本身FP就很快,所以效果肉眼几乎观察不出区别),nice,前端程序员的价值又体现了~(可惜我做的一些性能优化领导不知道,我这人比较腼腆,不善表达🥺)



🌈 概述



🍀 强制缓存


强制缓存

:设置缓存机制后,前端第一次请求到资源会把资源缓存到客户端,如果下次请求时资源没有过期,那么直接调用本地缓存的资源,如果过期则重新发送请求。


关键点 >>>

  • 强制缓存由

    服务端

    开启,利用

    http头

    中的

    Expires



    Cache-Control

    两个字段来控制

  • 客户端设置请求头

    Cache-Control

    ,只有为:

    no-store



    no-cache



    max-age=0

    才会生效(也就是客户端不想走强制缓存的时候生效。no-cache意思是不走强缓存,走协商缓存;no-store意思是不使用缓存),除非后端对这个字段做了处理;

  • 强制缓存不用和服务端交互;

  • 强缓存返回状态码为200;

  • post请求不能设置缓存,只有get请求有效。


补充说明 >>>



  1. Expires


    :response header里的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存(http1.0的产物,现在一般用cache-control)。
例如: expires: Thu, 03 Jan 2019 11:43:04 GMT

它是一个时间戳(准确点应该叫格林尼治时间), 当客户端再次请求该资源的时候, 会把客户端时间与该时间戳进行对比, 如果大于该时间戳则已过期, 否则直接使用该缓存资源。

但是, 有个

大问题

, 发送请求时是使用的客户端时间去对比。一是客户端和服务端时间可能快慢不一致, 另一方面是客户端的时间是可以自行修改的(比如浏览器是跟随系统时间的, 修改系统时间会影响到), 所以不一定满足预期。



  1. Cache-Control


    :cache-control主要有max-age和s-maxage、public和private、no-cache和no-store等值。例如当值设为max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。

在这里插入图片描述

图1.1 强缓存的响应头

在这里插入图片描述

图1.2 强缓存不和服务器交互,请求时间为0ms

  1. 控制台设置停用缓存其实就是在

    http 头

    里设置了

    cache-control: no-cache

image.png

图1.3 控制台停用缓存



🍀 协商缓存


协商缓存

:第一次请求资源时,服务器会返回资源以及资源标识,当下次请求时,会对比资源标识,如果一致,则只返回状态码304,不用返回资源,如果不一致,则会返回资源和新的资源标识。

协商缓存主要依赖的响应头包括

last-modified



ETag


关键点 >>>

  • 协商缓存需要和服务器交互;

  • 请求资源命中协商缓存后,返回的状态码为

    304

    ,所以304状态码不应该认为是一种错误,而是对客户端有缓存情况下服务端的一种响应;


响应头说明 >>>



  1. last-modified


    记录资源最后修改的时间。启用后, 请求资源之后的响应头会增加一个last-modified字段, 如下:
last-modified: Thu, 20 Dec 2018 11:36:00 GMT

但last-modified有以下两个缺点:

  • 🔥 只要编辑了, 不管内容是否真的有改变, 都会以这最后修改的时间作为判断依据, 当成新资源返回, 从而导致了没必要的请求相应, 而这正是缓存本来的作用即避免没必要的请求
  • 🔥 时间的精确度只能到秒, 如果在一秒内的修改是检测不到更新的, 仍会告知浏览器使用旧的缓存


  1. ETag


    的出现就是为了解决last-modified的上述问题。

    ETag

    会基于资源的内容编码生成一串唯一的标识字符串, 只要内容不同, 就会生成不同的ETag。启动ETag之后, 请求资源后的响应返回会增加一个ETag字段, 如下:
ETag: "ALJlkaasdkljasldjLSAJDakl_"

在这里插入图片描述

图2.1 缓存机制为协商缓存时首次进入页面的响应头

在这里插入图片描述

图2.2 第二次进入页面命中协商缓存后响应头

在这里插入图片描述

图2.2 图2.3 命中协商缓存后会发送请求,并且响应状态码为304



🌈 常用缓存策略

🍀 html:no-cache

🍀 js文件:max-age=2592000(一个月),s-maxage=86400;文件命名带版本号或指纹信息,方便及时更新。

🍀 CSS文件:max-age=2592000,s-maxage=3600;文件命名带版本号或指纹信息,方便及时更新。

图片:max-age=15552000;文件命名带版本号或指纹信息,方便及时更新。

🍀 XHR请求: no-cache

(s-maxage的优先级比max-age高。s-maxage是代理服务器的缓存时间)



🌈 如何配置缓存策略



🍀 前端配置缓存

  • 前端配置缓存只能设置html文件的缓存,对网页中的图片,js文件等其他静态资源无法配置,需要在nginx等服务器站点配置。

  • html页面设置缓存是在

    <head>

    标签中嵌入

    <meta>

    标签,如下:

//禁用缓存如下:
<meta http-equiv="pragma" content="no-cache">
// 仅有IE浏览器才识别的标签,不一定会在请求字段加上Pragma,但的确会让当前页面每次都发新请求
<meta http-equiv="cache-control" content="no-cache">
// 其他主流浏览器识别的标签
<meta http-equiv="expires" content="0">
// 仅有IE浏览器才识别的标签,该方式仅仅作为知会IE缓存时间的标记,你并不能在请求或响应报文中找到Expires字段


//设置缓存如下:
<meta http-equiv="Cache-Control" content="max-age=7200" />
// 其他主流浏览器识别的标签
<meta http-equiv="Expires" content="Mon, 20 Aug 2018 23:00:00 GMT" />
// 仅有IE浏览器才识别的标签



🍀 nginx配置示例

静态资源的缓存一般是在web服务器上配置的,常用的web服务器有:nginx、apache。这里列举下nginx的配置示例,具体location匹配正则规则,请按照自己项目需要进行匹配。

//示例1:强缓存时效为30s,30s后默认使用协商缓存,此时缓存时效优先级 > max-age
location / {
    add_header Cache-Control max-age=60;
    root   html;
    index  index.html index.htm;
    expires 30s;
}
//示例2: 只使用协商缓存
location / {
    # no-cache 禁用强缓存
    add_header Cache-Control no-cache;
    root   html;
    index  index.html index.htm;
}
//示例3: 强缓存 缓存时效 1小时
location / {
    root   html;
    index  index.html index.htm;
    expires 1h;
}



版权声明:本文为qq_38974163原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。