Webpack 性能之使用 Cache 提升构建性能_css-loader cache-loader

初始化,主要是根据配置信息设置内置的各类插件

Make - 构建阶段,从 entry 模块开始,执行:

  • 读入文件内容
  • 调用 Loader 转译文件内容
  • 调用 acorn 生成 AST 结构
  • 分析 AST,确定模块依赖列表
  • 遍历模块依赖列表,对每一个依赖模块重新执行上述流程,直到生成完整的模块依赖图 —— ModuleGraph 对象

Seal - 生成阶段,过程:

  • 代码转译,如 import 转换为 require 调用
  • 分析运行时依赖
  • 遍历模块依赖图,对每一个模块执行:
  • 合并模块代码与运行时代码,生成 chunk
  • 执行产物优化操作,如 Tree-shaking
  • 将最终结果写出到产物文件

过程中存在许多 CPU 密集型操作,例如调用 Loader 链加载文件时,遇到 babel-loader、eslint-loader、ts-loader 等工具时可能需要重复生成 AST;分析模块依赖信息时则需要遍历 AST,执行大量运算;Seal 阶段也同样存在大量 AST 遍历,以及代码转换、优化操作,等等。

实现缓存

在引入持久化缓存之前,Webpack 在每次运行时都需要对所有模块完整执行上述构建流程,假设业务项目中有 1000 个文件,则每次执行 npx webpack 命令时都需要从 0 开始执行 1000 次构建、生成逻辑。

而 Webpack5 的持久化缓存功能则尝试将构建结果保存到文件系统中,在下次编译时对比每一个文件的内容哈希或时间戳,未发生变化的文件跳过编译操作,直接使用缓存副本,减少重复计算;发生变更的模块则重新执行编译流程。缓存执行时机如下图:

如图,Webpack 在首次构建完毕后将 Module、Chunk、ModuleGraph 三类对象的状态序列化并记录到缓存文件中;在下次构建开始时,尝试读入并恢复这些对象的状态,从而跳过执行 Loader 链、解析 AST、解析依赖等耗时操作,提升编译性能。

用法详解

理解缓存的核心原理后,我们再回过头来看看 cache 提供的配置项列表,下面摘录几个比较常用的配置项:

官方文档:https://webpack.js.org/configuration/cache

  • cache.type:缓存类型,支持 ‘memory’ | ‘filesystem’,需要设置 filesystem 才能开启持久缓存
  • cache.cacheDirectory:缓存文件存放的路径,默认为 node_modules/.cache/webpack
  • cache.buildDependencies:额外的依赖文件,当这些文件内容发生变化时,缓存会完全失效而执行完整的编译构建,通常可设置为项目配置文件,如:
  1. module.exports = {
  2. cache: {
  3. buildDependencies: {
  4. config: [path.join(__dirname, ‘webpack.dll_config.js’)],
  5. },
  6. },
  7. };
  • cache.managedPaths:受控目录,Webpack 构建时会跳过新旧代码哈希值与时间戳的对比,直接使用缓存副本,默认值为 [‘./node_modules’]
  • cache.profile:是否输出缓存处理过程的详细日志,默认为 false
  • cache.maxAge:缓存失效时间,默认值为 5184000000

使用时通常关注上述配置项即可,其它如 idleTimeout、idleTimeoutAfterLargeChanges 等项均与 Webpack 内部实现算法有关,与缓存效果关系不大,无需关注。

Webpack 4 中的缓存

实际上,Webpack 4 已经内置使用内存实现的临时缓存功能,但必须在 watch 模式下使用,进程退出后立即失效,实用性不高。不过,在 Webpack 4 及之前版本中可以使用一些 loader 自带的缓存功能提升构建性能,例如 babel-loader、eslint-loader、cache-loader 。

开启babel-loader缓存

只需设置 cacheDirectory = true 即可开启 babel-loader 持久化缓存功能,例如:

  1. module.exports = {
  2. // …
  3. module: {
  4. rules: [{
  5. test: /.m?js$/,
  6. loader: ‘babel-loader’,
  7. options: {
  8. cacheDirectory: true,
  9. },
  10. }]
  11. },
  12. // …
  13. };

配置项说明:https://github.com/babel/babel-loader#options

以 Three.js 为例,开启缓存后生产环境构建耗时从 3500ms 降低到 1600ms;开发环境构建从 6400ms 降低到 4500ms,性能提升约 30% ~ 50% 。

默认情况下,babel-loader 会将缓存内容保存到 node_modules/.cache/babel-loader 目录,用户也可以通过 cacheDirectory = ‘dir’ 方式设置缓存路径。

开启eslint-loader缓存

eslint-loader 同样支持缓存功能,只需设置 cache = true 即可开启,如:

  1. module.exports = {
  2. // …
  3. module: {
  4. rules: [{
  5. test: /.js$/,
  6. exclude: /node_modules/,
  7. loader: ‘eslint-loader’,
  8. options: {
  9. cache: true,
  10. },
  11. }, ]
  12. },
  13. // …
  14. };

配置项说明:https://github.com/webpack-contrib/eslint-loader#cache

依然以 Three.js 为例,开启缓存后生产环境构建耗时从 6400ms 降低到 1400ms;开发环境构建从 7000ms 降低到 2100ms,性能提升达到 70% ~ 80%。

默认情况下,babel-loader 会将缓存内容保存到 ./node_modules/.cache/eslint-loader 目录,用户也可以通过 cache = ‘dir’ 方式设置缓存路径。

使用cache-loader

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

据知识点,真正体系化!**

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值