1

增量更新是目前大部分团队采用的缓存更新方案,能让用户在无感知的情况获取最新内容。具体实现方式通常是(一般我们通过构建工具来实现,比如webpack):

  • 构建产出文件hash(如:index.d94f83fac22c203b788c.css)
  • 更新html文件里静态资源的引用URL

由于其他资源是由html文件直接或间接引用才可以被加载,如果html里的静态资源URL更新了,那请求的肯定就是最新资源了。那我们需要考虑的就是如何确保加载的html是最新的了,其他的静态资源就充分利用浏览器缓存以减少网络请求提高web性能。浏览器缓存实质就是HTTP缓存,而HTTP缓存分为强缓存协商缓存

强缓存

强缓存不会发送请求,直接从浏览器加载资源。是否命中强缓存根据HTTP Response头部ExpiresCache-Controlmax-age)来判断。

  • Expires通过返回一个过期时间来判断是否过期,在此时间之前浏览器直接从缓存加载资源。但其缺点是返回的过期时间为服务器时间,而比较是同客户端时间比较,如果服务端和客户端存在时间误差就不准了。
  • max-age返回的时间过期时间跨度,比如max-age=3600告诉浏览器接下来的1小时内使用缓存。这样就解决了Expires时间误差导致的问题。

强缓存命中优先判断max-agemax-age优先级大于Expires,判断流程如下:
clipboard.png

协商缓存

  • EtagIf-None-Match Etag的值是根据一定算法生成的字符串,用以判断文件是否更改,类似于文件hash。在第一次访问时,服务会返回该文件的Etag值,在之后的访问通过在请求头增加If-None-Match参数,把Etag的值带过去,服务器通过比较Etag的值来判断是否需要重新返回最新资源(200 or 304)。
  • Last-ModifiedIf-Modified-Since Last-Modified为该资源文件的最后修改时间。同样在第一次返回,之后通过If-Modified-Since带过去,服务器通过比较值来判断是否需要返回最新资源。

如果 If-None-MatchIf-Modified-Since 都有,则必须一次性都发给服务器,没有优先级,实际中比较ETag就够了。如果请求头里没有,则每次都会返回最新的资源200

缓存判断流程

clipboard.png

为了确保html每次都是最新的,我们这里不能使用强缓存。可以在服务器(nginx、tomact)设置访问html文件时Cache-Control为no-cache。(这个需要在服务器配合设置,前端是处理不了的)


xuriliang
245 声望6 粉丝