一 目录
不折腾的前端,和咸鱼有什么区别
目录 | 一 目录 | 二 前言 | 三 针对 Webpack 本身构建优化 | 3.1 优化 resolve.modules 配置 | 3.2 优化 resolve.extensions 配置 | 3.3 优化 resolve.include/exclude 配置 | 四 通过 Loader 和 Plugin 优化 | 4.1 缓存 | 4.2 多进程 | 4.3 多进程压缩 | 4.4 静态资源分离 | 4.5 代码分离 | 4.6 打包资源压缩 | 五 其他优化点 | 5.1 Tree Shaking | 5.2 Scope Hoisting | 5.3 按需加载 | 六 优化体验 | 七 参考文献 |
---|
二 前言
Webpack 的优化瓶颈,主要是 2 个方面:
- Webpack 的构建过程太花时间
- Webpack 打包的结果体积太大
本文从这 2 个角度出发,收集一些相关优化资料。
三 针对 Webpack 本身构建优化
3.1 优化 resolve.modules 配置
resolve.modules
用于配置 Webpack
去哪些目录下寻找第三方模块,默认是 ['node_modules']
。
但是,它会先去当前目录的 ./node_modules
查找,没有的话再去 ../node_modules
,最后到根目录 —— 即 npm
查找包的规则。
所以可以直接指定项目根目录,这样代码就不需要一层一层查找。
resolve: {
modules: [path.resolve(__dirname, 'node_modules')],
}
3.2 优化 resolve.extensions 配置
在导入没带文件后缀的路径时,Webpack
会自动带上后缀去尝试询问文件是否存在,而 resolve.extensions
用于配置尝试后缀列表;默认为 extensions:['js', 'json']
。
当遇到 require('./data')
时 Webpack
会先尝试寻找 data.js
,没有再去找 data.json
;如果列表越长,或者正确的后缀越往后,尝试的次数就会越多。
所以在配置时为提升构建优化需遵守:
- 频率出现高的文件后缀优先放在前面。
- 列表尽可能的少,例如只有 3 个:
js
、jsx
、json
。 - 书写导入语句时,尽量写上后缀名。
3.3 优化 resolve.include/exclude 配置
以 babel-loader
为例,可以通过 include
和 exclude
帮助我们避免 node_modules
这类庞大文件夹。
即通过 include
告诉 Webpack
哪些我们是需要检测的,通过 exclude
告诉 Webpack
哪些我们是不需要检测的(例如已经收拾过的静态资源)
四 通过 Loader 和 Plugin 优化
4.1 缓存
- cache-loader
在 babel-loader
开启 cache
后,将 loader
的编译结果写进硬盘缓存,再次构建如果文件没有发生变化则会直接拉取缓存。
uglifyjs-webpack-plugin
通过这个插件也可以解决缓存问题。
4.2 多进程
由于有大量文件需要解析和处理,构建是文件读写和计算密集型的操作,特别是当文件数量变多后,Webpack
构建慢的问题会显得严重。
文件读写和计算操作是无法避免的,那能不能让 Webpack
同一时刻处理多个任务,发挥多核 CPU 电脑的威力,以提升构建速度呢?
Happypack
可以将任务分解成多个子进程去并发执行,大大提升打包效率。
除此之外 thread-loader
和 Happypack
一样,但是配置比较简单。
4.3 多进程压缩
因为自带的 UglifyjsWebpackPlugin
压缩插件是单线程运行的,而 TerserWebpackPlugin
可以并发运行压缩功能(多进程)。
所以通过 TerserWebpackPlugin
代替自带的 UglifyjsWebpackPlugin
插件。
4.4 静态资源分离
通过 DllPlugin
或者 Externals
进行静态依赖包的分离。
由于 CommonsChunkPlugin
每次构建会重新构建一次 vendor
,所以出于效率考虑,使用 DllPlugin
将第三方库单独打包到一个文件中,只有依赖自身发生版本变化时才会重新打包。
4.5 代码分离
在 Webpack
中,到底什么是代码分离?代码分离允许你把代码拆分到多个文件中。如果使用得当,你的应用性能会提高很多。因为浏览器能缓存你的代码。
每当你做出一次修改,包含修改的文件需要被所有访问你网站的人重新下载。但你并不会经常修改应用的依赖库。
如果你能把那些依赖库拆分到完全分离的文件中,即使业务逻辑发生了更改,访问者也不需要再次下载依赖库,直接使用之前的缓存就可以了。
由于有了 SplitChunksPlugin
,你可以把应用中的特定部分移至不同文件。如果一个模块在不止一个 chunk
中被使用,那么利用代码分离,该模块就可以在它们之间很好地被共享。
4.6 打包资源压缩
- JS 压缩:
UglifyjsWebpackPlugin
- HTML 压缩:
HtmlWebpackPlugin
- CSS 压缩:
MiniCssExtractPlugin
- 图片压缩:
image-webpack-loader
- Gzip 压缩:不包括图片
五 其他优化点
5.1 Tree Shaking
通过 ES6 的 import/export
来检查未引用代码,以及 sideEffects
来标记无副作用代码,最后用 UglifyJSPlugin
来做 Tree Shaking
,从而删除冗余代码。
5.2 Scope Hoisting
Scope Hoisting
是 Webpack3 的新功能,直译为 「作用域提升」,它可以让 Webpack 打包出来的 「代码文件更小」,「运行速度更快」。
熟悉 JavaScript 都应该知道 「函数提升」 和 「变量提升」 ,JavaScript 会把函数和变量声明提升到当前作用域的顶部。
「作用域提升」 也类似于此,Webpack 会把引入的 js 文件 “提升到” 它的引入者顶部。
Scope Hoisting
的实现原理其实很简单:分析出模块之间的依赖关系,尽可能将打散的模块合并到一个函数中,前提是不能造成代码冗余。因此「只有那些被引用了一次的模块才能被合并」。
由于 Scope Hoisting
需要分析出模块之间的依赖关系,因此源码「必须采用 ES6
模块化语句」,不然它将无法生效。原因和 Tree Shaking
中介绍的类似。
5.3 按需加载
- 什么是 代码分割(code splitting)?
代码分割是指:将脚本中无需立即调用的代码在代码构建时转变为异步加载的过程。
在 Webpack 构建时,会避免加载已声明要异步加载的代码,异步代码会被单独分离出一个文件,当代码实际调用时被加载至页面。
代码分割技术的核心是 异步加载资源。
可喜的是,浏览器允许我们这么做,W3C stage 3
规范: whatwg/loader 对其进行了定义:你可以通过 import()
关键字让浏览器在程序执行时异步加载相关资源。
在 Vue 中,可以直接使用 import()
关键字做到这一点,而在 React 中,你需要使用 react-loadable
去完成同样的事。
六 优化体验
- progress-bar-webpack-plugin:在终端底部,将会有一个构建的进度条,可以让你清晰的看见构建的执行进度。
- webpack-build-notifier:在构建完成时,能够像微信、Lark 这样的 APP 弹出消息的方式,提示构建已经完成。
- webpack-dashboard:对 Webpack 原始的构建输出不满意的话,也可以使用这样一款 Plugin 来优化你的输出界面。
- speed-measure-webpack-plugin:该插件可以测量各个插件和
loader
所花费的时间。 webpack-bundle-analyzer
:可视化分析。通过矩阵树图的方式将包内各个模块的大小和依赖关系呈现出来。webpack-chart
webpack-analyse
七 参考文献
2019 年文章:
- Webpack优化——将你的构建效率提速翻倍【阅读建议:10min】
- 性能优化篇---Webpack构建速度优化【阅读建议:10min】
- 使用webpack4提升180%编译速度【阅读建议:10min】
- 多进程并行压缩代码【阅读建议:5min】
- webpack 4: Code Splitting和chunks切分优化【阅读建议:5min】
2018 年文章:
- Tree-Shaking性能优化实践 - 原理篇【阅读建议:10min】
- 体积减少80%!释放webpack tree-shaking的真正潜力【阅读建议:10min】
- 你的Tree-Shaking并没什么卵用【阅读建议:5min】
- webpack 如何通过作用域分析消除无用代码【阅读建议:5min】
- 让你的Webpack起飞—考拉会员后台Webpack优化实战【阅读建议:5min】
- webpack dllPlugin打包体积和速度优化【阅读建议:5min】
- webpack优化之code splitting【阅读建议:5min】
2017 年文章:
- Webpack 打包优化之速度篇【阅读建议:5min】
- 加速Webpack-缩小文件搜索范围【阅读建议:5min】
- Webpack 大法之 Code Splitting【阅读建议:5min】
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!