前言
随着前端工程越来越复杂,项目代码也越来越多,Webpack已经成为前端开发中必不可少的工具。Webpack 不仅可以将多个 JavaScript 文件打包成一个文件、还可以轻松处理图像、字体等其他资源。但是随着代码逐渐增大,Webpack 打包的速度也变得越来越慢,长时间的等待导致开发效率的下降,必须要进行打包速度的优化。
在本文中,我们将讨论如何提高 Webpack 打包速度的方法以及如何优化 Webpack 加载时间,深入探讨 Webpack 体验优化的各种技术,让您的打包速度得到显著提升。
Webpack 打包速度优化
1. 减少文件搜索范围
我们可以减少 Webpack 搜索文件的范围来提高打包速度,有几种方法可以实现:
使用 resolve
在 Webpack 配置文件中使用
resolve
属性可以减少 Webpack 对文件的搜索范围,例如:-- -------------------- ---- ------- -------------- - - ----- -------- - ----------- ------- ------- ------ ------- --------- ------ - ---- ----------------------- -------- -- -- --
上面的配置选项让 Webpack 只对指定的文件类型进行搜索,而不是对所有类型进行搜索。同时通过设置
alias
可以让 Webpack 更快地搜索到指定目录中的文件。
改变 target
我们可以改变 Webpack 的
target
,默认情况下,Webpack 打包时,会搜索所有的node_modules
目录下的所有包。如果您的项目并不需要打包这些
node_modules
的包,可以考虑切换成node
目标,因为不需要考虑浏览器或者其他运行环境的兼容性问题。
module.exports = { //... target: 'node', };
2. 优化 loader
在 Webpack 打包文件的过程中,loader
负责处理 JavaScript 文件以及其他资源,这些 loader
对代码打包速度有直接影响。我们可以通过以下方法来优化 loader
的工作:
减少处理文件的数量
当配置文件中的 exclude
和 include
属性设置好之后,Webpack 转化文件的数量就会减少,加快了打包速度。
-- -------------------- ---- ------- -------------- - - ----- ------- - ------ - - ----- -------- -------- --------------- -------- ------ ------- --------------- -- -- -- --
编译 WebAssembly
WebAssembly(简写为 wasm)是一种新的编译目标,它具有 Web 平台的能力,并且可以比 JavaScript 更快地运行。Webpack 支持 wasm 代码的打包和编译,通过使用 wasm-loader
可以将 wasm 文件编译为 JavaScript 代码,并且可以提升代码性能。
-- -------------------- ---- ------- -------------- - - ----- ------- - ------ - - ----- ---------- ----- ------------------- -- -- -- --
3. 插件使用
Webpack 也提供了一些插件,他们可以优化开发体验和打包速度。
使用HappyPack
HappyPack
是一个插件,用于将代码的加载与处理分离,并将代码都转移到后台线程中,从而提高 Webpack 的构建速度。通过使用 happypack
将代码加载和编译分类,大大提高了构建速度。
- 首先安装
happypack
npm install happypack -D
- 然后在 Webpack 配置文件中增加以下配置:
-- -------------------- ---- ------- ------------------- ----- --------- - --------------------- -------------- - - ----- ------- - ------ - - ----- -------- -------- --------------- -------- ------ ---- ------------------------- -- -- -- -------- - --- ----------- --- ----- -------- - - ------- --------------- -- -- --- -- --
在 loaders 选项中可以指定要使用的 loader,然后通过 plugins 配置来启用。
使用 IgnorePlugin
IgnorePlugin
是一个插件,用于忽略指定的模块,避免将不需要的模块打包到最终的文件中,从而减少了打包时间。
const webpack = require('webpack'); module.exports = { plugins: [new webpack.IgnorePlugin(/\.\/locale/, /moment$/)], };
上述的代码可以将 moment
中的 locale
移除掉,最终生成的文件将会更小,打包的速度也会更快。
使用 DllReferencePlugin
DllReferencePlugin
是一个非常实用的插件,将第三方库单独打包,从而提高打包速度。不必再每次构建打包时,都需要将这些库重新打包一遍,而是将其预编译,随后在拼接编译后的代码中进行引用。
需要在 DllPlugin
中单独打包出一个 chunk
(we.js),在 HtmlWebpackPlugin
中引用到打包出的文件。
-- -------------------- ---- ------- ----------------------- ----- ---- - ---------------- ----- - --------- - - ------------------- -------------- - - ----- ------------- ------ - --- --------- ------------ --------------------- -- ------- - --------- ---------------- ----- ----------------------- ---------- -------- --------- -- -------- - --- ----------- ----- --------- ----- ----------------------- ------------------------------- --- -- --
-- -------------------- ---- ------- ------------------- ----- ---- - ---------------- ----- ----------------- - ------------------------------- ----- - ------------------ - - ------------------- -------------- - - ----- -------------- ------ ----------------- ------- - --------- --------------------- ----- ----------------------- ----------- -- ------- - ----- -- -------- - --- ------------------- --------- ---------------------- --------- ------------- ------- - ---------------------- ----- ------------------- ----- -- --- --- -------------------- --------- ----------------------- -------------------------- -- -- --
Webpack 加载优化
1. 分割代码
前端的工程化带来的复杂性是很多人都知道的,其中一个重要的问题就是会使我们生成巨大的 JavaScript 文件,特别是对于使用某些框架,比如 React 或 Angular 等,由于它们内部都有很多的功能和库,很容易将文件数量和文件大小爆炸式增长。浏览器在处理大量 JavaScript 代码时,会变得非常缓慢。
此时可以考虑将一个大型代码文件拆分成多个文件,并适时加载,以减少文件的大小和加载时间。Webpack 中提供了很多拆分代码的方法,其中比较流行的也是最推荐的是使用 import()
动态加载。
import()
会返回一个 Promise,在调用后会异步地加载模块并返回一个模块对象。通过这个方法,可以将代码拆分为更小的代码块,只加载需要的代码块,并在适当的时候加载代码块,以提高首次加载时间和后续重新加载时间。
下面是一个使用 import()
动态加载的示例:
-- -------------------- ---- ------- ----- ----------- ------- --------------- - ------- - -- -- - -------------------------------------------------- -- - ------------------------------ --- -- -------- - ------ - ----- ------- ---------------------------- ------------ ------ - - -
2. 缓存loader
在开发过程中,多次修改代码,Webpack 需要反复编译,此时缓存 loader 的产出可以加速编译过程。
文档中有很多类似的方法,my-loader是官方提供的测试 loader,如果发现缓存实现不了比较奇怪的打包缓慢的问题,可以使用这个方法来在 loader 中打印调试下。
-- -------------------- ---- ------- ------------------- ----- ---- - ---------------- ----- ------- - ------------------- -------------- - - ----- ------- - ------ - - ----- -------- -------- --------------- -------- ------ ---- - - ------- --------------- -------- - --------------- --------- ----- -- -- -- -- -- -- -- --
3. 懒加载和预加载
- 懒加载,在需要时加载,提高页面加载效率。例如当图片中的许多部分都无需初始化时,可以将这些图片的初始化推迟到浏览器看到它前。
- 预加载,预加载能够很好地提升页面加载过程中的并行性能。通过预加载,可以在请求资源之前将其缓存,从而在需要时秒级加载。
懒加载
React.lazy()
是在 React v16.6 引入的一种新的方式,是一个高阶组件。它使得能够动态地加载某些组件,这些组件在浏览器浏览页面及其剩余元素后,随即再加载。懒加载可以减少渲染时间并提高页面加载速度,特别是对于大型代码库。除此之外,React.lazy() 也是之前加载组件方式的改进,例如 Route 和 Code Splitting。
-- -------------------- ---- ------- ------ ------ - ----- -------- - ---- -------- ----- -------------- - ------- -- ---------------------------- ----- ---------------- - ------- -- ------------------------------ -------- ------------- - ------ - ----- --------- --------------------------------- --------- --------------- -- ----------------- -- ---------- ----------- ------ -- -
上面的 example 中,通过调用 React.lazy()
并传入返回 Promise 的模块才会懒加载模块。
预加载
除了懒加载以外,Webpack 还支持预加载,通过预加载可以提高应用的响应时间,这是因为在用户访问其他页面之前,资源已被下载到浏览器中。
import(/* webpackPrefetch: true */ 'LoginModal.jsx');
上面代码使用 Webpack 进行代码分割,并在请求有可能被用户点击的代码时启动,并在后台请求加载。
总结
Webpack 是一个非常强大和有用的前端工具,我们为此提供了一些有用的技巧,以确保您的代码可以快速高效地打包。优化打包速度不仅可以提高开发效率,还能为用户提供更好的用户体验。在构建大型的前端应用程序时,这些技巧尤为重要,可以帮助您减少代码的大小、缩短加载时间,以及提高应用程序的性能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64f946caf6b2d6eab30d6212