67 HTTP缓存及Nginx配置优化 - xiaoxin01/Blog GitHub Wiki

HTTP缓存响应

请求一个资源时,会得到的响应与缓存相关的有如下3种:

  1. 200
  2. 304 Not Modified
  3. 200 (from xxx cache)

第一次请求资源,或者资源过期时,会得到上面第1个响应,这种情况下,client会向Server发起一次请求。

非第一次请求资源,但资源超过了设置的缓存时间,并且自上次请求以后服务端没有修改,会得到上面第2个响应,这种情况下,client也会向Server发起一次请求。

非第一次请求资源,且资源没有超过设置的缓存时间,会得到上面第3个响应,这种情况下,client不会向Server发起请求。

结论

如果要提升性能,尽可能的让资源返回第3种响应,其次第2种。

200 (from xxx cache) 响应

通过设置 Cache-Control(http/1.1)或 Expires(http/1.0),可以让浏览器在client端先进行过期验证而无需向Server发起请求。

比如某次请求,response header如下:

Cache-Control:max-age=15
Content-Type:text/css
Date:Tue, 24 Oct 2017 07:51:49 GMT
Expires:Tue, 24 Oct 2017 07:52:04 GMT
Last-Modified:Wed, 18 Oct 2017 01:23:11 GMT

表示该资源从 Date 表示的时间开始,有效时间为 15 秒,在client端时间小于 Date + 15 秒之前,再次访问该资源,浏览器会直接返回 200 (from xxx cache) 而不会向Server发送请求。

需要注意的是,Date为server返回的时间,如果server的时间和client时间不吻合,可能会导致client感知到的缓存有效时间与 max-age 声明的时间不同。

304 Not Modified

当资源超过了 200 (from xxx cache) 的有效期,再次请求该资源时,client会将 Last-Modified 的信息作为 Request Header的If-Modified_Since字段发送给Server,用于判断服务器的资源是否有变化,如果没有变化,则会返回 304 Not Modified

Nginx启用gzip之后,ETag带来的问题

实际测试发现,Nginx启用gzip之后,即使原始资源没有改变, If-None-Match 和 If-Modified_Since 都没有变化,仍然会返回 200 而不是 304 Not Modified,可以通过去除ETag Header解决:

proxy_hide_header ETag;

另外的解决途径可能是通过 weak etag。

Nginx配置缓存

expires 15s;

做如上配置之后,Nginx会自动在response header生成 Cache-Control:max-age=15 和 Expires

参考:

⚠️ **GitHub.com Fallback** ⚠️