现代前端应用应如何配置 HTTP 缓存机制
Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 600
Author 回答者: shfshanyue
参考: 前端项目中的缓存配置
关于 http 缓存配置的最佳实践为以下两条:
- 文件路径中带有 hash 值:一年的强缓存。因为该文件的内容发生变化时,会生成一个带有新的 hash 值的 URL。前端将会发起一个新的 URL 的请求。配置响应头
Cache-Control: public,max-age=31536000,immutable
- 文件路径中不带有 hash 值:协商缓存。大部分为
public
下文件。配置响应头Cache-Control: no-cache
与etag/last-modified
但是当处理永久缓存时,切记不可打包为一个大的 bundle.js
,此时一行业务代码的改变,将导致整个项目的永久缓存失效,此时需要按代码更新频率分为多个 chunk 进行打包,可细粒度控制缓存。
webpack-runtime
: 应用中的webpack
的版本比较稳定,分离出来,保证长久的永久缓存react/react-dom
:react
的版本更新频次也较低vendor
: 常用的第三方模块打包在一起,如lodash
,classnames
基本上每个页面都会引用到,但是它们的更新频率会更高一些。另外对低频次使用的第三方模块不要打进来pageA
: A 页面,当 A 页面的组件发生变更后,它的缓存将会失效pageB
: B 页面echarts
: 不常用且过大的第三方模块单独打包mathjax
: 不常用且过大的第三方模块单独打包jspdf
: 不常用且过大的第三方模块单独打包
在 webpack5
中可以使用以下配置:
{
// Automatically split vendor and commons
// https://twitter.com/wSokra/status/969633336732905474
// https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
splitChunks: {
chunks: 'all',
},
// Keep the runtime chunk separated to enable long term caching
// https://twitter.com/wSokra/status/969679223278505985
// https://github.com/facebook/create-react-app/issues/5358
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`,
},
}
Author 回答者: maya1900
具体在代码里哪里配置呢?都在webpack配置里?
Author 回答者: shfshanyue
@maya1900 都在 nginx 配置里,见 https://q.shanyue.tech/deploy/cra-route.html#nginx-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
# 解决单页应用服务端路由的问题
try_files $uri $uri/ /index.html;
# 非带 hash 的资源,需要配置 Cache-Control: no-cache,避免浏览器默认为强缓存
expires -1;
}
location /static {
# 带 hash 的资源,需要配置长期缓存
expires 1y;
}
}
Author 回答者: maya1900
@maya1900 都在 nginx 配置里,见 https://q.shanyue.tech/deploy/cra-route.html#nginx-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6
server { listen 80; server_name localhost; root /usr/share/nginx/html; index index.html index.htm; location / { # 解决单页应用服务端路由的问题 try_files $uri $uri/ /index.html; # 非带 hash 的资源,需要配置 Cache-Control: no-cache,避免浏览器默认为强缓存 expires -1; } location /static { # 带 hash 的资源,需要配置长期缓存 expires 1y; } }
谢谢月哥!