Skip to content

浏览器缓存(HTTP缓存) #12

@edwineo

Description

@edwineo

DNS 缓存

什么是 DNS

全称 Domain Name System,即域名系统。

万维网上作为域名IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。DNS协议运行在UDP协议之上,使用端口号53。

DNS 解析

通过域名,最终得到该域名所对应的IP地址的过程叫做域名解析(或主机名解析)。

www.dnscache.com (域名)  - DNS解析 -> 11.222.33.444 (IP地址)

DNS 缓存

有 DNS 的地方,就有缓存。浏览器、操作系统、Local DNS、根域名服务器,它们都会对DNS结果做一定程度的缓存。

DNS 查询过程如下:

  1. 首先搜索浏览器自身的 DNS 缓存,如果存在,则域名解析到此完成。
  2. 如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的 hosts 文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。
  3. 如果本地 hosts 文件不存在映射关系,则查找本地 DNS 服务器(ISP 服务器,或者自己手动设置的 DNS 服务器),如果存在,域名到此解析完成。
  4. 如果本地 DNS 服务器还没找到的话,它就会向根服务器发出请求,进行递归查询。

CDN 缓存

什么是 CDN

全称 Content Delivery Network,即内容分发网络。

摘录一个形象的比喻,来理解 CDN 是什么。

10年前,还没有火车票代售点一说,12306.cn更是无从说起。那时候火车票还只能在火车站的售票大厅购买,而我所在的小县城并不通火车,火车票都要去市里的火车站购买,而从我家到县城再到市里,来回就是4个小时车程,简直就是浪费生命。后来就好了,小县城里出现了火车票代售点,甚至乡镇上也有了代售点,可以直接在代售点购买火车票,方便了不少,全市人民再也不用在一个点苦逼的排队买票了。

简单的理解 CDN 就是这些代售点(缓存服务器)的承包商,他为买票者提供了便利,帮助他们在最近的地方(最近的 CDN 节点)用最短的时间(最短的请求时间)买到票(拿到资源),这样去火车站售票大厅排队的人也就少了。也就减轻了售票大厅的压力(起到分流作用,减轻服务器负载压力)。

用户在浏览网站的时候,CDN 会选择一个离用户最近的 CDN 边缘节点来响应用户的请求,这样海南移动用户的请求就不会千里迢迢跑到北京电信机房的服务器(假设源站部署在北京电信机房)上了。

CDN 缓存

关于 CDN 缓存,在浏览器本地缓存失效后,浏览器会向 CDN 边缘节点发起请求。类似浏览器缓存,CDN边缘节点也存在着一套缓存机制。CDN 边缘节点缓存策略因服务商不同而不同,但一般都会遵循 http 标准协议,通过http响应头中的 Cache-control: max-age 的字段来设置 CDN 边缘节点数据缓存时间。

当浏览器向 CDN 节点请求数据时,CDN 节点会判断缓存数据是否过期,若缓存数据并没有过期,则直接将缓存数据返回给客户端。否则,CDN节点就会向服务器发出回源请求,从服务器拉取最新数据,更新本地缓存,并将最新数据返回给客户端。 CDN服务商一般会提供基于文件后缀、目录多个维度来指定 CDN 缓存时间,为用户提供更精细化的缓存管理。

CDN 优势

  1. CDN 节点解决了跨运营商和跨地域访问的问题,访问延时大大降低。
  2. 大部分请求在 CDN 边缘节点完成,CDN 起到了分流作用,减轻了源服务器的负载。

浏览器缓存

什么是浏览器缓存

简单来说,浏览器缓存其实就是浏览器保存通过 HTTP 获取的所有资源,是浏览器将网络资源存储在本地的一种行为。

缓存的资源去哪了?

你可能会有疑问,浏览器存储了资源,那它把资源存储在哪里呢?存储在以下两个部分

  1. memory cache

    MemoryCache 顾名思义,就是将资源缓存到内存中,等待下次访问时不需要重新下载资源,而直接从内存中获取。Webkit 早已支持 memoryCache。 目前 Webkit 资源分成两类,一类是主资源,比如 HTML 页面,或者下载项,一类是派生资源,比如HTML 页面中内嵌的图片或者脚本链接,分别对应代码中两个类:MainResourceLoader 和 SubresourceLoader。虽然 Webkit支持 memoryCache,但是也只是针对派生资源,它对应的类为 CachedResource,用于保存原始数据(比如CSS,JS等),以及解码过的图片数据。

  2. disk cache

    DiskCache 顾名思义,就是将资源缓存到磁盘中,等待下次访问时不需要重新下载资源,而直接从磁盘中获取,它的直接操作对象为 CurlCacheManager。

  3. 以下是他们的对比

    memory cache disk cache
    相同点 只能存储一些派生类资源文件 只能存储一些派生类资源文件
    不同点 退出进程时数据会被清除 退出进程时数据不会被清除
    存储资源 一般脚本、字体、图片会存在内存当中 一般非脚本会存在内存当中,如css等

    因为CSS文件加载一次就可渲染出来,我们不会频繁读取它,所以它不适合缓存到内存中,但是js之类的脚本却随时可能会执行,如果脚本在磁盘当中,我们在执行脚本的时候需要从磁盘取到内存中来,这样IO开销就很大了,有可能导致浏览器失去响应。

三级缓存原理(访问缓存优先级)

  • 先在内存中查找,如果有,直接加载。
  • 如果内存中不存在,则在硬盘中查找,如果有直接加载。
  • 如果硬盘中也没有,那么就进行网络请求。
  • 请求获取的资源缓存到硬盘和内存。

浏览器缓存的分类

  1. 强缓存
  2. 协商缓存

浏览器再向服务器请求资源时,首先判断是否命中强缓存,再判断是否命中协商缓存。

浏览器缓存的优点

  1. 减少了冗余的数据传输
  2. 减少了服务器的负担,大大提升了网站的性能
  3. 加快了客户端加载网页的速度

强缓存

浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。

这里的 header 中的信息指的是 expires 和 cache-control

Expires

该字段是 http1.0 时的规范,它的值为一个绝对时间的 GMT 格式的时间字符串,比如 Expires:Mon,18 Oct 2066 23:59:59 GMT。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。

Cache-Control

Cache-Control 是 http1.1 时出现的 header 信息,主要是利用该字段的 max-age 值来进行判断,它是一个相对时间,例如 Cache-Control:max-age=3600,代表着资源的有效期是 3600 秒。cache-control 除了该字段外,还有下面几个比较常见的属性:

Cache-Control请求头常见属性

字段(单位秒) 说明
max-age=300 拒绝接受长于300秒的资源,为0时表示获取最新资源
max-stale=100 缓存过期之后的100秒内,依然拿来用
min-fresh=50 缓存到期时间还剩余50秒开始,就不给拿了,不新鲜了
no-cache 协商缓存验证
no-store 不使用缓存
only-if-chached 只使用缓存,没有就报504错误
no-transform 不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Type等HTTP头不能由代理修改。然并卵

Cache-Control响应头常见属性

字段(单位秒) 说明
max-age=300 缓存有效期300秒
s-maxage=500 有效期500秒,优先级高于max-age,适用于共享缓存(如CDN)
public 可以被任何终端缓存,包括代理服务器、CDN等
private 只能被用户的浏览器终端缓存(私有缓存)
no-cache 需要和服务端确认资源是否发生变化,没有变化则使用缓存
no-store 不缓存
no-transform 与上面请求指令中的一样
must-revalidate 客户端缓存过期了就向源服务器验证
proxy-revalidate 代理缓存过期了就去源服务器重新获取

http 缓存 -强制缓存

协商缓存

协商缓存就是强缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。

http 缓存-协商缓存

资源标识分为两种:

Last-Modified / If-Modified-Since

Last-Modified 是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。

If-Modified-Since 则是客户端再次发起该请求时,携带上次请求返回的 Last-Modified 值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。服务器收到该请求,发现请求头含有 If-Modified-Since 字段,则会根据 If-Modified-Since 的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于 If-Modified-Since 的字段值,则重新返回资源,状态码为 200;否则则返回 304,代表资源无更新,可继续使用缓存文件。

Etag / If-None-Match

Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。

If-None-Match 是客户端再次发起该请求时,携带上次请求返回的唯一标识 Etag 值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后,发现该请求头中含有 If-None-Match,则会根据 If-None-Match 的字段值与该资源在服务器的 Etag 值做对比,一致则返回 304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200。

Etag / If-None-Match 优先级高于 Last-Modified / If-Modified-Since,同时存在则只有Etag / If-None-Match生效。通常使用Etag,因为其更精确些,而 Last-Modified 只能精确到秒

整个流程

http 缓存-综述

正常操作:强缓存有效,协商缓存有效

手动刷新(F5):强缓存失效,协商缓存有效

强制刷新(ctrl + F5):强缓存失效,协商缓存失效

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions