最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 浅析HTTP缓存

    正文概述 掘金(字节前端)   2021-03-29   600

    1. 为什么需要缓存

    • 通过缓存机制,可以在相应场景下复用以前获取的资源。
    • 显著提高网站的性能和响应速度
    • 减少网络流量和等待渲染时间
    • 降低服务器压力

    2. HTTP缓存类型

    • 强缓存
    • 协商缓存

    3. 强缓存

    对于强缓存,服务器返回的静态资源响应头会设置一个强制缓存的时间,在缓存时间内,如刷新浏览器请求相同资源,在缓存时间未过期的情况下,则直接使用已缓存资源。如缓存资源已过期,执行协商缓存策略。

    • 以下为与强缓存相关的HTTP头部字段
    字段用途实例优先级HTTP版本
    Expires强缓存的过期日期Expires:Thu,06 Aug 2021 14:36:18 GMT1.0Cache-Control指定指令实现缓存机制Cache-Control:max-age=601.1

    3.1 Expires

    • 响应头Expires字段包含强缓存资源的过期时间
    • 值为0表示资源已过期或非强缓存

    3.2 Cache-Control

    通用消息头字段,通过指令来实现缓存机制。说明一下容易弄混的两个字段,其他指令参考指令大全。

    • no-cache

    在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)。

    • no-store

    缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。

    3.3 Expires 和 Cache-Control 的区别

    • 时间区别
      • Expires 过期时间为绝对时间,指未来某个时间点缓存过期。
      • Cache-Control 为相对时间,相对于当前时间,如 60s 后缓存过期
    • 优先级
      • Expires 的优先级低于 Cache-Control 字段
      • 同时存在 Cache-ControlExpires时,以 Cache-Control 指令为准
    • HTTP 版本
      • Expires 是HTTP/1.0 提出的,其浏览器兼容性更好
      • Cache-Control 是 HTTP/1.1 提出的,浏览器兼容性不佳,所以 ExpiresCache-Control 可以同时存在,在不支持 Cache-Control的浏览器则以Expires为准

    4. 协商缓存

    • 协商缓存即和服务器协商是否使用缓存,通过判断后决定重新加载资源 or HTTP StatusCode 304
    • 以下字段决定是否使用协商缓存,而非强缓存:
    字段协商缓存优先级
    PragmaPragma:no-cacheCache-ControlCache-Control:no-cache / Cache-Control:max-age=

    4.1 Pragma

    • Pragma是一个HTTP1.0中规定的通用首部,如果Cache-Control不存在的话,它的行为与Cache-Control: no-cache一致。强制要求缓存服务器在返回缓存的版本之前将请求提交到源头服务器进行协商验证。
    • Pragma的值就只有一个,no-cache,并且它的优先级比Cache-Control高。

    4.2 Cache-Control

    • 上文介绍过Cache-Control,它的指令既可以用于强缓存又可应用于协商缓存策略中
    • 其中Cache-Control: no-cacheCache-Control: max-age=0 的作用一样,强制要求发起请求给服务器进行验证 (协商资源验证)。

    5. 协商策略

    当出现Pragma字段或者Cache-Control:no-cache时,就需要使用协商策略,常见的两对协商缓存字段如下

    • ETag/If-None-Match
    • Last-Modified/If-Modfied-Since
    字段对应字段描述优先级
    Last-ModifiedIf-Modified-SinceGMT时间服务端资源的最后修改时间If-Modified-SinceLast-ModifiedGMT时间上次请求响应头的Last-Modified,验证是否为服务端资源最后修改的时间,是返回304,否返回200。EtagIf-None-Match内容hash/文件信息服务器缓存资源的文件信息或文件内容生成的哈希值If-None-MatchEtag内容hash/文件信息上次请求响应头的ETag,验证服务器资源有没有修改,有返回200,没有返回304。

    优缺点

    • 如果服务端修改了一段代码,然后又改回去了。
      • 此时资源文件的修改时间变了
      • 实际上文件没有发生改变
      • 这样缓存就失效了,产生了不必要的传输
    • 而ETag可以根据内容生成的hash来比较的,只要资源文件内容不变,就会应用客户端的缓存,减少不必要的传输。
    • 所以ETag比Last-Modified缓存更精确、高效和节省带宽。

    6. ETag

    6.1 什么是ETag?

    Etag是 Entity tag的缩写,可以理解为“被请求资源的摘要标识”,Etag是服务端的一个资源的标识,在 HTTP 响应头中将其传送到客户端,类似这样,ETag:W/"50b1c1d4f775c61:df3"

    6.2 ETag格式

    • ETag:W/"xxxxxxxx"
    • ETag:"xxxxxxx"

    强类型验证

    • 比对资源每个字节都要一样。

    W/前缀代表使用弱类型验证

    • 不需要每个字节都一样,例如页脚的时间or展示的广告不一样,都可以认为是一样的。构建应用于弱验证类型的标签(etag)体系可能会比较复杂,因为这会涉及到对页面上不同的元素的重要性进行排序,但是会对缓存性能优化相当有帮助。

    6.3 ETag生成需要满足什么条件?

    1. 当文件更改时,ETag值必须改变
    2. 尽量便于计算,不会特别耗CPU。
    3. 利用摘要算法生成(MD5, SHA128, SHA256)需慎重考虑,这些为CPU密集型运算。
    4. 不是不能用。没有最好的算法,只有适合对应场景的算法。
    5. 必须横向扩展,分布式部署时多个服务器节点上生成的ETag值保持一致。

    6.4 ETag是怎么生成的(Nginx)

    Nginx的源码中ETag由last_modified和content_length拼接而成

    etag->value.len = ngx_sprintf(etag->value.data, "\"%xT-%xO\"",
                                      r->headers_out.last_modified_time,
                                      r->headers_out.content_length_n)
                          - etag->value.data;  
    
    • 翻译为以下伪代码
    etag = header.last_modified + "-" + header.content_lenth
    
    • 总结:Nginx中ETag由响应头的Last-ModifiedContent-Length表示为十六进制组合而成。

    Lodash网站请求检验

    浅析HTTP缓存

    const LAST_MODIFIED = new Date(parseInt('5fc4907d', 16) * 1000).toJSON()
    const CONTENT_LENGTH = parseInt('f48', 16)
    
    console.log(LAST_MODIFIED) // 2020-11-30T06:26:05.000Z
    console.log(CONTENT_LENGTH) // 3912
    
    • 输出结果

    浅析HTTP缓存

    • 既然在nginxETagLast-ModifiedContent-Length组成,那它便算是一个加强版的Last-Modified了,那加强在什么地方呢?
    • Last-Modified只能作用于秒级的改变,而 nginx 中的 ETag 添加了文件大小的附加条件,不仅和修改时间有关,也和内容有关,使之更加精确。

    6.5 Last-Modified是怎么生成的

    在linux中

    • mtimemodified time指文件内容改变的时间戳
    • ctimechange time指文件属性改变的时间戳,属性包括mtime。而在 windows 上,它表示的是creation time
    • 而HTTP服务选择Last-Modified时一般会选择mtime,表示文件内容修改的时间,来兼容Windows和Linux。
    • 以下为nginx源码
        r->headers_out.status = NGX_HTTP_OK;     
        r->headers_out.content_length_n = of.size;     
        r->headers_out.last_modified_time = of.mtime;
    

    6.6 如果 http 响应头中 ETag 值改变了,是否意味着文件内容一定已经更改?

    • 不一定
    • 文件在一秒内发生了改变而且文件大小不变
    • 这种情况非常极端,概率很低
    • 因此在正常情况下可以容忍一个不太完美但是高效的算法。

    欢迎关注「 字节前端 ByteFE 」 简历投递联系邮箱「tech@bytedance.com」


    起源地下载网 » 浅析HTTP缓存

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元