长期缓存

Long Term Cache

使用 webpack 等打包器进行打包时,每个资源都可生成一个带有 hash 的路径。如

  • build/main.071b73.js
  • build/main.94474e.css
  • build/logo.18bac8.png

此处对添加 hash 的资源设置永久缓存,可大幅度提高该网站的缓存能力,从而大幅度提高网站的二次加载性能。

通过在服务器端/网关端对资源设置以下 Response Header,进行强缓存一年时间,称为永久缓存,即 Long Term Cache

1
Cache-Control: public,max-age=31536000,immutable

而当源文件内容发生变更时,资源的 hash 发生变化,生成新的可永久缓存的资源地址。

因此在实践中,可对打包处理后带有 hash 资源的所有文件设置永久缓存。

如果前端通过 docker/k8s/helm 进行部署,可由团队人员自行在构建 nginx 镜像时进行添加响应头字段。此处可作为前端性能优化的 kpi/okr。

可在浏览器控制台 Network 中查看响应头来验证所属项目是否已成功添加永久缓存。

image

一个问题与更强的永久缓存

假设有两个文件: index.jslib.js,且 index 依赖于 lib,其内容如下。

index.js

1
2
// index.js
import('./lib').then(o => console.log(o))

lib.js

1
export const a = 3

由 webpack 等打包器打包后将会生生两个 chunk (为了方便讲解,以下 aaaaaa 为 hash 值)

  • index.aaaaaa.js
  • lib.aaaaaa.js

问: 假设 lib.js 文件内容发生变更,index.js 由于引用了 lib.js,可能包含其文件名,那么它的 hash 是否会发生变动

答: 不一定。打包后的 index.js 中引用 lib 时并不会包含 lib.aaaaaa.js,而是采用 chunkId 的形式,如果 chunkId 是固定的话,则不会发生变更。

1
2
3
4
5
// 打包前
import('./lib')

// 打包后,201 为固定的 chunkId (chunkIds = deterministic 时)
__webpack_require__.e(/* import() | lib */ 201)

在 webpack 中,通过 optimization.chunkIds 可设置确定的 chunId,来增强 Long Term Cache 能力。

1
2
3
4
5
{
optimization: {
chunkIds: 'deterministic'
}
}

设置该选项且 lib.js 内容发生变更后,打包 chunk 如下,仅仅 lib.js 路径发生了变更。

  • index.aaaaaa.js
  • lib.bbbbbb.js