使用 webpack 打包时,如何更好地利用 long term cache
::: tip Issue 欢迎在 Gtihub Issue 中回答或反馈问题: Issue 81 :::
Long Term Cache
使用 webpack
等打包器进行打包时,每个资源都可生成一个带有 hash 的路径。如
build/main.071b73.js
build/main.94474e.css
build/logo.18bac8.png
此处对添加 hash
的资源设置永久缓存,可大幅度提高该网站的缓存能力,从而大幅度提高网站的二次加载性能。
通过在服务器端/网关端对资源设置以下 Response Header,进行强缓存一年时间,称为永久缓存,即 Long Term Cache
。
Cache-Control: public,max-age=31536000,immutable
而当源文件内容发生变更时,资源的 hash
发生变化,生成新的可永久缓存的资源地址。
因此在实践中,可对打包处理后带有 hash 资源的所有文件设置永久缓存。
如果前端通过 docker/k8s/helm 进行部署,可由团队人员自行在构建 nginx 镜像时进行添加响应头字段。此处可作为前端性能优化的 kpi/okr。
可在浏览器控制台 Network 中查看响应头来验证所属项目是否已成功添加永久缓存。
一个问题与更强的永久缓存
假设有两个文件: index.js
和 lib.js
,且 index 依赖于 lib,其内容如下。
index.js
// index.js
import("./lib").then((o) => console.log(o));
lib.js
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 是固定的话,则不会发生变更。
// 打包前
import("./lib");
// 打包后,201 为固定的 chunkId (chunkIds = deterministic 时)
__webpack_require__.e(/* import() | lib */ 201);
在 webpack 中,通过 optimization.chunkIds
可设置确定的 chunId,来增强 Long Term Cache 能力。
{
optimization: {
chunkIds: 'deterministic'
}
}
设置该选项且 lib.js
内容发生变更后,打包 chunk 如下,仅仅 lib.js
路径发生了变更。
index.aaaaaa.js
lib.bbbbbb.js