客户端浏览器的缓存

  • 利用本地缓存,localstorage, sessionstorage。属于代码架构层面的优化措施,不属于前端工程体系的服务范围
  • 利用http缓存策略,分为强制缓存(根据过期时间决定是否请求)和协商缓存(每次发出请求,服务器比对后,决定是否使用本地还是新资源)。采用哪种策略由http协议的headers(首部)信息决定

增量更新

  • 是目前大部分团队采用的缓存更新方案
  • 结合强制缓存策略,既能够保证用户第一时间获取最新资源,又能减少网络资源消耗,提高web应用的执行速度
  • 前端工程体系的作用:
  1. 构建产生文件hash指纹,这是实现增量更新的必要条件
  2. 构建更新html文件对其他静态资源文件的引用url

expires 和 max-age

  • 都是强制缓存的关键信息
  • expires指定明确时间点作为过期时间点。缺点,服务器时间和客户端时间不一致。
  • cache-control,更加精准地控制缓存,有以下几种信息
  1. no-cache(协商缓存),先和服务器确认是否发生变化,没有变化就用本地的
  2. no-store,禁止浏览器和所有中间缓存存储任何版本的响应,每次都要请求
  3. public,浏览器和中间缓存器可以无限期缓存,这个不常用
  4. private,浏览器可以缓存,中间缓存器不可以缓存。比如浏览器可以缓存包含用户信息的html文件,但是cdn不可以。
  5. max-age,缓存的最长时间,比如1个小时

Etag和if-none-match

  • Etag是服务器为资源分配的字符串形式的唯一性标识,在首部信息中返回给浏览器
  • 浏览器在cache-control指定no-cache或者max-age和expires都过期,将Etag通过if-none-match作为首部信息发送给服务器。服务器对比Etag值是否变化。没有变化,返回304 not modified,根据缓存策略返回新的cache-control信息。变化了,返回最新资源,和新的Etag。

协商缓存的优点

  • 非服务器端渲染的html,由于它是所有静态资源的引用者,必须保证它是最新的
  • 为了便于服务器解析和网站地址的唯一性,html不能用hash指纹
  • 所以html可以用协商缓存
覆盖更新和增量更新
  • 前提都是强制缓存策略
  • 增量更新的实现方案是为文件名添加hash指纹
  • 覆盖更新缺陷多已经被淘汰了
静态资源url后面的v参数的意义
  • 唯一的作用就是让浏览器更新资源
  • 参数如果能够和文件内容一一对应,就实现了有针对性修改参数,这就是hash指纹
  • hash指纹,通过数据摘要算法(目前使用广泛的是md5)计算出文件的hash值
覆盖更新缺陷
  1. 必须保住html文件和改动的静态文件同步更新
  • 不是服务器端渲染的html,会被当作静态资源,会同时和其他静态资源一起部署。这样能保证同步更新,不会受到覆盖更新的缺陷影响
  • 服务器端渲染的html,会和静态资源分开部署,就会有时间差,时间差内的页面就会出错。所以很多网站就会在半夜人少的时候更新版本
  1. 不利于版本回滚。覆盖更新每次都会覆盖服务器上的旧版本文件,对版本回滚操作不友好。
增量更新
  • 将原本作为参数值的hash指纹,作为资源文件的名称的一部分,删除用于更新的url参数
  • 静态资源先于html部署
  • 修改了文件名称,不会覆盖旧版本的文件,回滚操作只需要回滚html
  • 优化了版本控制,还可以支持多版本共存
同步模块的修改对异步文件和主文件hash指纹的影响
  • 同步模块构建后,与主模块合并为主文件,同步加载。对异步文件没有影响
  • 异步模块构建后,为单独的异步文件,按需加载
异步模块的修改对主模块的hash指纹的影响
  • 异步模块,影响其对应异步文件的hash
  • 主文件的hash也必须同步修改,否则拿不到最新的异步文件
hash
  • webpack本身有计算hash的功能
  • hash的定义:the hash of the compilation
  • webpack的compilation对象代表某个版本对应的资源编译过程
  • webpack每次检测到项目文件有改动就会创建一个compilation,进而生成新的编译文件
  • compilation不是针对单个文件,而是所有参与构建的文件。只有有一个文件改动,compilation对象就会变化,compilation的hash值就会变化。
  • 构建的所有文件,不论同步还是异步,都拥有相同的hash指纹
  • 这个方案不合理,不适用于增量更新
chunkhash
  • chunk,散列的模块合并成一个个块
  • chunkhash,就是一个个块,根据自身的代码内容计算得到的hash值
contenthash
  • 就是解耦js和css文件hash指纹的关键
  • contenthash不是webpack自身的另外一种hash值,而是ExtractTextPlugin插件提供
  • 主文件的hash和css的hash完全不同,各自hash改变只能是因为各自文件改变