http缓存之基本概念

前言

1. 重要性

  • 在初级程序员阶段对此关注并不多,工作中也极少遇到;到了中级水平,面试中会被频繁问到,特别是中大型公司
  • 缓存也是 web 性能优化的必要手段
  • 对于静态资源的缓存设置,目前一般都是后端、运维通过 nginx、apache 等在配置文件中具体设置的,但是很显然他们不会主动去设置,这里需要有一个引导者,这个引导者毫无疑问应该是前端了,因为缓存极大的提高了页面加载速度,最大受益者是前端,前端不懂 这方面的知识,恐怕和后端、运维都无法沟通。

综上所述,所以大家很有必要花时间来研究。

2. 困难之处
个人认为http缓存是比较枯燥的理论知识,尤其对于前端来讲,更多在于理解概念,以及内部缓存机制,而没有什么实践可以巩固,或者说理论和现实脱轨。

问题

  1. 如何利用http缓存进行性能优化?
  2. 项目上线后,客户需要手动更新后才能访问到最新变化,如何避免?
  3. 当有缓存时,浏览器还会向服务器发起请求吗?

基本概念

浏览器会在请求资源之后,根据自己的缓存策略判断是否对资源进行缓存,当再次请求相同的资源时,浏览器根据缓存策略判断是通过本地缓存获取资源,还是重新向服务器发起请求。

这个 缓存策略 到底是什么呢?
实际每个浏览器的缓存策略是有差异的,但大致受以下几个因素的影响。

http缓存之基本概念_第1张图片
浏览器缓存策略

Html meta 属性控制缓存

搜索关键字 禁止 html 缓存,很容易搜到以下答案:




但是,这是 Html 4.0 中的规范,在 Html 5.0 的规范中 http-equiv 已经不存在以上属性值了。
而且代理服务器并不会读取以上meta标签,不利于代理服务器的缓存。

Generally, you'd better just not specify the HTML meta tags to avoid confusion by starters, and rely on hard HTTP response headers. Moreover, specifically those tags are invalidin HTML5. Only the http-equiv values listed in HTML5 specification are allowed.

-- 引用自 stackoverflow

综上所述,html meta 是一个不那么可靠,并且已经过时的解决方案,所以不建议再继续使用

HTTP 缓存策略

基于 HTTP 协议的缓存策略,分为 强缓存协商缓存, 由 HTTP 协议的首部 (Headers) 信息决定。具体的操作设置需要服务器配合,比如 Nginx 。所以相对来说都是后端在做此类事情,前端接触的机会比较少。

http缓存之基本概念_第2张图片
http缓存.png
强缓存

如果开启了强缓存,并且在过期时间之内,则浏览器不再发起请求,直接使用本地的缓存资源。
Expires 和 Cache-control 用于控制强制缓存。

  1. Expires

Expires 是 HTTP 1.0 的特性。通过指定一个明确的时间点作为缓存资源的过期时间,客户端会根据此时间点来判断到底使用本地缓存,还是向服务器重新请求资源。

优点: 在缓存过期时间内,减少客户端的 HTTP 请求,不仅节省了客户端处理时间,提高了 web 应用的执行速度,而且减少了服务器负载,以及客户端网络资源的消耗。

缺点:指定的过期时间以服务器为准,但是客户端进行过期时间判断时是将本地的时间指定的过期时间点进行对比。如果客户端修改了本地时间,将会影响对缓存的判断。

  1. Cache-control

Cache-control 是HTTP1.1 新增的特性,以便更精准地控制缓存。此首部信息 具有最高的优先级。

描述
no-store 禁止浏览器以及所有中间缓存存储任何版本的返回响应。每次用户都会向服务器发送请求,并下载完整的响应。
no-cache 先与服务器确认返回的响应是否变化,如果资源未发生变化,则可使用缓存副本从而避免下载。
max-age 指定从请求的时刻开始计算,此响应的缓存副本有效的最长时间 (单位:s)
public 响应可以被浏览器以及中间缓存无限期缓存
private 响应可以被浏览器缓存,但是不允许任何中间缓存器对其进行缓存。

max-age 指定的是缓存的时间跨度,而非缓存失效的时间点。优先级比 Expires 高。

协商缓存

如果需要使用协商缓存,需要 将 Cache-control 指定为 no-cache 或者 max-age 、Expires 均过期之后。

协商缓存:浏览器本地是有缓存的,但是要先发起请求,由服务器判断缓存是否过期。

Last-Modified / If-Modified-Since


last-Modified 是 HTTP 1.0 的特性,是服务器端在响应请求时用来说明资源的最后修改时间。

  1. 首次请求资源时,服务器端在响应请求中通过字段 Last-Modified 说明资源的最后修改时间。
  2. 再次请求该资源时,浏览器发送的 http 请求头中将通过字段 If-Modified-Since 把 Last-Modified的值带给服务器端,由服务器来判断该资源是否过期。
  • 未过期:将返回状态码 304 ,并且不返回 实体响应
  • 过期: 将返回状态码 200 , 并且返回最新资源, 当然 Last-Modified 也会被更新为最新的修改时间。

缺点:

  1. 只能精确到秒级
  2. 内容没变化,时间变化了,也会被认为是变化

Etag / If-None-Match


Etag 是 HTTP 1.1 的特性,是服务器为资源分配的字符串形式唯一性标识,作为响应首部返回给浏览器。

采用弱比较,内容没变化,时间变化了,会认为是资源未变化。

  1. 首次请求资源时,服务器端在响应请求中通过字段 Etag 说明资源的唯一标识。
  2. 再次请求该资源时,浏览器发送的 http 请求头中将通过字段 If-None-Match 把 Etag 的值带给服务器端,由服务器来判断该资源是否过期。
  • 未过期:将返回状态码 304 ,并且不返回 实体响应
  • 过期: 将返回状态码 200 , 并且返回最新资源, 当然 Etag 也会被更新。

参考

浏览器之HTTP缓存的那些事
304和浏览器http缓存
浏览器缓存机制剖析
浏览器缓存机制介绍
技术研究 vue项目的性能优化之路
HTTP缓存控制小结

你可能感兴趣的:(http缓存之基本概念)