Webpack5文件资源缓存

要说文件资源缓存那就得先了解一下浏览器的缓存机制

浏览器大概可以分为强制缓存(强缓存)和协商缓存

浏览器每次与服务器通信的方式为应答模式,即:浏览器发起HTTP请求 – 服务器响应该请求。那么浏览器第一次向服务器发起该请求后拿到请求结果,会根据响应报文中HTTP头的缓存标识,决定是否缓存结果,是则将请求结果和缓存标识存入浏览器缓存中,简单的过程图如下:

由上图我们可以知道:

  • 浏览器每次发起请求,都会先在浏览器缓存中查找该请求的结果以及缓存标识

  • 浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中

这里我们来着重说一下强制缓存

强制缓存

强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程,强制缓存的情况主要有三种(暂不分析协商缓存过程),如下:

不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致),如下图:

存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存(暂不分析),如下图

 

存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果,如下图 

那么强制缓存的缓存规则是什么?

当浏览器向服务器发起请求时,服务器会将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Control优先级比Expires高。

在我们的HTTP/1.1中Expire已经被Cache-Control替代,所以这里我就只说明Cache-Control。

Cache-Control

在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,主要取值为:

  • public:所有内容都将被缓存(客户端和代理服务器都可缓存)

  • private:所有内容只有客户端可以缓存,Cache-Control的默认取值

  • no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定

  • no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存

  • max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效

接下来我们看一个例子:

如上图,这里的 Cache-Control设立了public和max-age说明该请求的所有内容在规定的时间内会被强制缓存,即就是如果该请求文件名称不发生变化的化会一直读取缓存文件。

第一次请求:

 当刷新页面再次请求:


接下来说说文件资源缓存在打包过程中的处理方式

为了让代码上线运行缓存更好使用,我们在webpack打包过程中,如果修改了相应的css或者js文件的话,因为浏览器的强缓存机制,在打包后我们的页面是不会发生变动的,所以在我们的webpack中需要对打包后的文件名进行相应的处理,去告诉浏览器这是个新的文件(发生变动的文件)需要重新请求资源。

在webpack中输出文件通常有三种命名方式:

 hash:每次webpack打包会生成一个唯一的hash值

       问题:因为js和css同时使用一个hash值 如果重新打包会导致所有缓存失效(可能我只改动一个文件)

chunkhash:根据chunk生成hash值。如果打包来源同一个chunk,那么hash值一样

       问题:js和css的hash值还是一样,因为css是在js中被引入的,所以同属于一个chunk

contenthash:根据文件的内容生成hash值。不同文件的hash值一定不一样

上述方法可以看出使用contenthash的方式输出文件是最好的方法。


接下来说说babel的缓存原理

我们在webpack中使用babel-loader是去为了兼容我们的js代码,将更高级的语法转译成浏览器所能识别语法。

为了确保这个过程更加快速准确,我们可以看一下官方文档是怎么做的

下面是我的做法

这里开启了cacheDirectory缓存,可以让我们的转译结果进行一个本地缓存,在我们之后的打包过程中如果js没有进行修改的话可以直接从缓存中读取文件进行输出,我来解释一下cacheDirectory缓存的原理

cacheDirectory原理

当有设置cacheDirectory时,指定的目录将用来缓存loader的执行结果。之后的 webpack 构建,将会尝试读取缓存,来避免在每次执行时,可能产生的、高性能消耗的Babel重新编译过程。如果设置了一个空值 (loader: 'babel-loader?cacheDirectory') 或者 true (loader: babel-loader?cacheDirectory=true),loader 将使用默认的缓存目录 node_modules/.cache/babel-loader,如果在任何根目录下都没有找到 node_modules 目录,将会降级回退到操作系统默认的临时文件目录。

原文

### 使用 Webpack 实现静态资源缓存的最佳实践 #### 一、Webpack 静态资源缓存的核心理念 Webpack 是一种模块打包工具,它能够通过一系列插件和配置项优化前端项目的构建流程。为了实现高效的静态资源缓存Webpack 提供了多种方法来确保生成的文件具有唯一的标识符(通常是哈希值)。这样做的目的是当文件内容发生改变时,新生成的文件名也随之变化,从而避免浏览器加载陈旧的缓存文件[^1]。 --- #### 二、具体实现方式 ##### 1. **为输出文件添加哈希值** 在 Webpack 的 `output` 配置中,可以通过占位符 `[hash]` 或 `[contenthash]` 动态注入文件内容对应的哈希值。这种做法可以有效区分不同版本的文件,防止缓存命中错误。 ```javascript module.exports = { output: { filename: 'js/[name].[contenthash].bundle.js', // JavaScript 文件带 contenthash chunkFilename: 'js/[name].[contenthash].chunk.js' // 动态导入的 Chunk 文件也带上 hash }, }; ``` 这里的 `[contenthash]` 只会根据文件的实际内容计算得出,只有当文件内容发生变化时才会触发新的哈希值生成[^2]。 --- ##### 2. **分离 CSS 文件并为其添加哈希值** 对于样式表文件,建议使用 `MiniCssExtractPlugin` 插件将其从 JavaScript 中提取出来,并同样附加上哈希值作为文件名的一部分。 ```javascript const MiniCssExtractPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { module: { rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], }, ], }, plugins: [ new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash].css', // 输出的 CSS 文件名包含 contenthash }), ], }; ``` 此配置不仅实现了 CSS 文件的独立输出,还通过 `[contenthash]` 确保了缓存的有效性[^2]。 --- ##### 3. **压缩与优化静态资源** 为了让最终生成的文件体积更小、加载更快,可以引入一些常用的优化插件,例如 `TerserWebpackPlugin` 和 `OptimizeCSSAssetsPlugin`。它们分别用于压缩 JavaScript 和 CSS 资源。 ```javascript const TerserPlugin = require('terser-webpack-plugin'); const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); module.exports = { optimization: { minimizer: [ new TerserPlugin(), new OptimizeCSSAssetsPlugin(), ], }, }; ``` 以上配置会在生产环境中自动运行,进一步提升性能表现。 --- ##### 4. **导出资源映射表** 有时可能需要记录所有生成的静态资源路径及其对应关系,这时可以借助 `webpack-manifest-plugin` 或类似的工具生成一份 JSON 文件。 ```javascript const WebpackManifestPlugin = require('webpack-manifest-plugin'); module.exports = { plugins: [ new WebpackManifestPlugin({ fileName: 'asset-manifest.json', // 自定义输出文件名 }), ], }; ``` 这份 JSON 文件可以帮助开发者更好地管理和调试项目中的静态资源[^3]。 --- #### 三、HTTP 缓存策略的补充 虽然 Webpack 主要负责生成带有哈希值的文件名,但在部署阶段还需要正确设置 HTTP 响应头以充分利用浏览器缓存机制。例如: - 对于 HTML 文件,推荐设置较短的缓存时间或者禁用缓存 (`Cache-Control: no-cache`)。 - 对于其他静态资源(如 JS、CSS、图片等),可设置较长的缓存时间(如一年)并通过 ETag 或 Last-Modified 进行校验。 典型配置如下: ```nginx location /static/ { expires 1y; # 设置最长缓存时间为 1 年 add_header Cache-Control "public"; } ``` 这样的组合可以让用户首次访问时快速下载所需资源,之后多次访问直接利用本地缓存,显著改善体验。 --- ### 总结 通过合理配置 Webpack 的输出规则、启用插件优化以及结合 HTTP 缓存策略,可以有效地实现静态资源的持久化缓存目标。这种方法不仅能减少不必要的网络请求次数,还能加快页面加载速度,进而提升整体用户体验。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值