首页 JavaScript源码正文

http缓存简介

景先 源码 2019-07-10 407 0

http缓存

都是服务端通过配置http headers来告诉浏览器是否能缓存,以及缓存多长时间。

强缓存:不去请求服务端,直接从本地缓存读取资源。

协商缓存:请求服务端,返回304,然后从本地缓存读取资源。

强缓存

浏览器不会去请求服务器,主要通过expirescache-control控制。

nginx通过配置expires指令,来控制缓存有效期。


location ~ .*\.(js|css)?$
{
    expires      1d; # 缓存一天
}

配置成功后,会在Response Headers中添加ExpiresCache-control字段。

如上述缓存一天的配置,最终的Response Headers会是这样:

Cache-control的值表示最大缓存时间,即一天(60 * 60 * 24 = 86400秒),是一个相对值。

Date为当前请求的时间。

Expires为缓存过期时间。

Expireshttp1.0的功能,为一个绝对时间。如果浏览器的时间小于Expires的时间,则命中强缓存,直接从缓存读取资源。不过浏览器和服务端的时间可能会出现比较大的误差,所以http1.1新增了Cache-control

浏览器在第一次请求成功之后,会将该Response Headers缓存。下次请求的时候,浏览器会先从缓存的Response Headers中读取DateCache-control的值计算出缓存有效期。如果浏览器的时间没有超过缓存有效期,则命中强缓存,直接从缓存读取资源。

优先级Cache-control > Expires

from disk cache && from memory cache

Chrome employs two caches — an on-disk cache and a very fast in-memory cache. The lifetime of an in-memory cache is attached to the lifetime of a render process, which roughly corresponds to a tab. Requests that are answered from the in-memory cache are invisible to the web request API. If a request handler changes its behavior (for example, the behavior according to which requests are blocked), a simple page refresh might not respect this changed behavior. To make sure the behavior change goes through, call handlerBehaviorChanged() to flush the in-memory cache. But don’t do it often; flushing the cache is a very expensive operation. You don’t need to call handlerBehaviorChanged() after registering or unregistering an event listener.

内存缓存是和渲染进程绑定的,大部分情况下与浏览器Tab对应。

协商缓存

主要通过ETagLast-Modified来控制。

nginx默认都是开启状态。

静态资源默认都会打上ETag,通过添加etag off指令禁止生成ETag

Last-Modified表示此文件在服务期端最后被修改的时间。

<img src="https://ws3.sinaimg.cn/large/006tKfTcly1fss25hltwwj30lu0iw3zc.jpg" width="400">

Last-modified / If-Modified-Since: 浏览器首先请求资源时,服务端在Response Headers返回请求的资源上次修改时间,就是Last-modified,浏览器会缓存下这个时间。然后浏览器在下次请求中,Request Headers中会带上If-Modified-Since(保存的Last-modified的值)。服务端接收到这个值后,会与资源的修改时间做对比,如果一致,则返回304,浏览器从缓存读取资源。

last-modified依赖的是一个绝对时间值,可能各机器读到的时间不一致,就会出现误差,为了改善这个问题,就有了ETag

ETag / If-None-Match: HTTP协议定义ETag为”被请求变量的实体值”,也可以理解为Web资源关联的记号(token)。

生成ETag常用的方法包括对资源内容使用抗碰撞散列函数,使用最近修改的时间戳的哈希值,甚至只是一个版本号。和last-modified一样,浏览器会先发送一个请求得到ETag的值,然后再下一次请求在Request Headers中带上If-None-Match(保存的ETag的值)。通过这个值进行对比,如一致,则返回304,浏览器从缓存读取资源。

<br />
<br />
<br />

参考资料

http缓存

Node.js描述 HTTP 中最基本的缓存机制

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

评论