前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浏览器缓存

浏览器缓存

作者头像
IMWeb前端团队
发布2019-12-03 18:22:28
2.2K0
发布2019-12-03 18:22:28
举报
文章被收录于专栏:IMWeb前端团队

本文作者:IMWeb 存勖闲 原文出处:IMWeb社区 未经同意,禁止转载

原文链接:http://www.cun-xu.cn/index.php/2018/12/26/浏览器缓存/

今天我们来说一下浏览器缓存的问题,缓存可以减少网络IO的消耗,提高访问速度。浏览器缓存是一种操作简单、效果显著的前端性能优化手段。

关于缓存的头部字段包括:

cache-control(缓存头)
  • 每个资源都可通过cache-controlHTTP标头定义其缓存策略
  • cache-control指令控制谁在什么条件下可以缓存响应以及可以缓存多少
可缓存性

public: 即使它有相关联的http身份验证,甚至响应状态代码通常无法缓存,也可以缓存响应。大多数情况下,public不是必需的,因为明确的缓存信息(例如max-age)已表示响应是可以缓存的。

private: 浏览器可以缓存private响应。不过,这些响应通常只为单个用户缓存,因此不允许任何中间缓存对其进行缓存。例如,用户的浏览器可以缓存包含私人信息的HTML网页,但CDN却不能进行缓存。

no-cache: 表示必须先与服务器确认返回的响应是否发生了变化,然后才能使用该响应来满足后续对同一网址的请求。因此,如果存在合适的验证令牌(Etag),no-cache会发起往返通信来验证缓存的响应,但如果资源未发生变化,则可避免下载。有的时候只设置no-cache防止缓存还是不够保险,还可以加上private指令,将过期时间设为过去的时间。

到期

max-age=(seconds) 指令指定从请求的时间开始,允许获取的响应被重用的最长时间(单位:秒)。例如,"max-age=60"表示可在接下来的60秒缓存和重用响应。

s-maxage=(seconds):同max-age,只用于共享缓存(比如CDN缓存) 比如,当s-maxage=60时,在这60秒钟,即使更新了CDN的内容,浏览器也不会进行请求。也就是说max-age用与普通缓存,而s-maxage用于代理缓存,如果存在s-maxage,则会覆盖掉max-ageExpiresheader。

max-stale=(seconds) 为发起端设置,即使缓存已经到期,但在max-stale设置的时间内还可以使用过期的缓存。

重新验证

must-revalidate 缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。

proxy-revalidatemust-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。

其他

no-store 直接禁止浏览器以及所有中间缓存存储任何版本的返回响应,例如,包含个人隐私数据或银行业务数据的响应。每次用户请求该资源时,都会向服务器发送请求,并下载完整的响应。

no-transform 不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Type等HTTP头不能由代理修改。例如,非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。 no-transform指令不允许这样做。

Pragma

当该字段值为no-cache的时候。会告诉浏览器不要对该资源缓存,及每一次都得向服务器发送一次响应。

代码语言:javascript
复制
res.serHeader('Pragma','no-cache')                                //禁止缓存
res.setHeader('Cache-Control','public,max-age=120')   //2分钟

通过Pragma来禁止缓存,通过Cache-Control设置两分钟缓存,但是重新访问我们会发现浏览器会再次发起一次请求,说明了Pragma的优先级高于Cache-Control

Expires

缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires = max-age + 请求时间,需要和Last-modified结合使用。但在上面我们提到过,cache-control的优先级更高。Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前可以直接从浏览器缓存取数据,而无需再次请求。

Last-Modified 上次修改时间

服务器端文件的最后修改时间,需要和catch-control共同使用,是检查服务器资源是否更新的一种方式。当浏览器再次进行请求时,会向服务器传送If-Modified-Since报头,询问Last-Modified时间点之后资源是否被修改过。如果没有修改,则返回码为304,使用缓存;如果修改过,则再次去服务器请求资源,返回码和首次请求相同为200,资源为服务器最新资源。

Etag 数据签名

根据试题内容生成一段哈希字符串,标识资源的状态,由服务器产生。浏览器会将这串字符串传回服务器,验证资源是否已被修改,如果没有修改,过程如下:

使用Etag可以解决Last-modified存在的一些问题:

  • 某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新
  • 如果某些资源修改非常频繁,在秒一下的时间内进行修改,而last-modified只能精确到秒。
  • 一些资源的最后修改时间改变了,但是内容没改变,使用Etag就认为资源还是没有修改的

根据查到的资料显示,缓存头的优先级是这样的:

代码语言:javascript
复制
Pragma > Cache-Control > Expires > Etag > Last-Modified

缓存策略

至于缓存策略的制定,我们可以参照Google官方的这张图

由于图上都是英文,我猜像我这样的菜鸟都看不懂,这里借资料来解释一下:

当我们的资源内容不可复用时,直接为 Cache-Control 设置no-store,拒绝一切形式的缓存;否则考虑是否每次都需要向服务器进行缓存有效确认,如果需要,那么设 Cache-Control 的值为 no-cache;否则考虑该资源是否可以被代理服务器缓存,根据其结果决定是设置为 private 还是public;然后考虑该资源的过期时间,设置对应的 max-ages-maxage 值;最后,配置协商缓存需要用到的 Etag、Last-Modified等参数。

根据上面的基础知识和解读,我们可以知晓:在制定缓存策略时,需要牢记以下技巧:

  • 使用一致的网址:如果您在不同的网址上提供相同的内容,将会多次获取和存储这些内容。提示:网址区分大小写。
  • 确保服务器提供验证令牌(Etag):有了验证令牌,当服务器上的资源未发生变化时,就不需要传送相同的字节。
  • 确定中间缓存可以缓存哪些资源:对所有用户的响应完全相同的资源非常适合由CDN以及其他中间缓存进行缓存。
  • 为每个资源确定最佳缓存周期:不同的资源可能有不同的更新要求。为每个资源审核并确定合适的max-age
  • 确定最合适您的网站的缓存层次结构:您可以通过为HTML文档组合使用包含内容指纹的资源网址和短时间或no-cache周期,来控制客户端获取更新的速度。
  • 最大限度减少搅动:某些资源的更新比其他资源频繁。如果资源的特定部分(例如JavaScript函数或CSS样式集)会经常更新,可以考虑将其代码作为单独的文件提供。这样一来,每次获取更新时,其余内容(例如变化不是很频繁的内容库代码)可以从缓存获取,从而最大限度减少下载的内容大小

文章的最后我们还要说一下内存缓存(from memory cache)和硬盘缓存(from disk cache)。

内存缓存

内存缓存有两个特点,分别是快速读取和时效性。

  • 快速读取:内存换粗会将编译解析后的文件,直接存入该进程的内存中,占据该进程一定的内存资源,以便下次运行时的快速读取
  • 时效性:一旦该进程关闭,则该进程的内存会被清空
硬盘缓存

硬盘缓存- 则是将缓存直接写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度比内存缓存慢。

那么哪些文件会被放入内存中呢?

事实上,这个划分规则,一直以来是没有定论的。不过想想也可以理解,内存时有限的,很多时候需要先考虑即时呈现的内存余量,再根据具体的情况决定分配给内存和磁盘的资源量的比重——资源存放的位置具有一定的随机性。

虽然划分规则没有定论,但根据日常开发中观察的结果,我们至少可以总结出这样的规律:资源存不存内存,浏览器秉承的是“节约原则”。我们发现,Base64格式的图片,几乎永远可以被塞进memory cache,这可以视作浏览器为节省渲染开销的“自保行为”;此外,体积不大的 JS、CSS 文件,也有较大地被写入内存的几率——相比之下,较大的 JS、CSS 文件就没有这个待遇了,内存资源是有限的,它们往往被直接甩进磁盘。

浏览器读取缓存的顺序为memory –> disk

好啦,着急忙慌整完了,正好零点,碎觉碎觉。 明天还要考试,关老爷保佑!!!

参考文章: https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=zh-cn http://www.alloyteam.com/2016/03/discussion-on-web-caching/#prettyPhoto

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-12-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • cache-control(缓存头)
    • 可缓存性
      • 到期
        • 重新验证
          • 其他
          • Pragma
          • Expires
          • Last-Modified 上次修改时间
          • Etag 数据签名
          • 缓存策略
            • 内存缓存
              • 硬盘缓存
              相关产品与服务
              对象存储
              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档