# Long Term Cache

> 使用 webpack 等打包器进行打包时，每个资源都可生成一个带有 hash 的路径。如 + build/main.071b73.js + build/main.94474e.css + build/logo.18bac8.png 此处对添加 hash 的资源设置永久缓存，可大幅度提高该网站的缓存能力，从而大幅度提高网站的二次加载性能。

- 发布于: 2019-06-07
- 更新于: 2026-09-30
- 原文: https://shanyue.tech/posts/frontend-engineering/cache/
- 标签: frontend-engineering
- 专栏: 前端工程化

---

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

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

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

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

```bash
Cache-Control: public,max-age=31536000,immutable
```

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

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

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

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

![](https://shanyue.tech/images/assets/2021-11-29/clipboard-1625.748311.webp)

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

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

**index.js**

```js
// index.js
import("./lib").then(o => console.log(o));
```

**lib.js**

```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 是固定的话，则不会发生变更。

```js
// 打包前
import("./lib");

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

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

```bash
{
  optimization: {
    chunkIds: 'deterministic'
  }
}
```

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

- `index.aaaaaa.js`
- `lib.bbbbbb.js`
