webpack性能优化总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack性能优化总结相关的知识,希望对你有一定的参考价值。
一.缩小文件的搜索范围
- 优化Loader配置
使用配置项include与exclude尽可能高概率命中文件,减少webpack匹配文件的时间。
我们可以适当的配置项目的结构目录。module.exports = { module: { rules: [{ test: /\.js?$/, include: path.resolve(__dirname, ‘app‘), use: { loader: ‘babel-loader?cacheDirectory‘, options: { presets: [‘es2015‘, ‘react‘, "stage-0"] } } }], }, }
- 优化resolve.modules
指定模块路径,不需要按照默认的方式一层一层查找文件夹, 指定modules配置下的app目录方便在引入其他组件可以以绝对路径引入。引入方式如下截图:
module.exports = {
resolve: {
extensions: [‘.js‘, ‘.jsx‘],
modules: [
path.resolve(dirname, ‘app‘),
path.resolve(dirname, ‘node_modules‘)
]
}
}
ReactEcharts是npm安装的模块,Input是自己写在公共组件components的文件夹,由于components在app文件夹下
根据配置,可以直接以此种方式引入。 - 优化resolve.extensions
此配置项默认配置为:
extensions: [‘js‘, ‘json‘]
如果这个数组列表越长, 或者正确的后缀越往后, 就会造成尝试的次数越多,所以resolve.extensions尽量减少后缀尝试的可能性。建立配置为:
extensions: [‘js‘],
二. 使用DLLPLUGIN
为什么web项目构建介入动态连接库的思想后,会大大提升构建速度呢?原因在于,包含大量复用模块的动态链接库只需被编译一次,在之后的构建过程中被动态链接库包含的模块将不会被重新编译,而是直接使用动态连接库中的代码。要给web项目构建接入动态链接库的思想,需要完成以下事情。
- 将网页依赖的基础模块抽离出来,打包成一个个单独的动态链接库中。在一个动态链接库中可以包含多个模块。
- 当需要导入的模块存在于某个动态链接库,这个模块不能再次打包,而是去动态链接库中去获取。
- 页面依赖的所有动态链接库都需要被加载。
下面以react项目为例。
webpack已经内置了对动态链接库的插件Dllplugin以及DllReferencePlugin
首先看构建成功之后的目录结构
以及构建webpack的配置,下图是webpack_dll.config.js文件:
下图是webpack配置主文件的重要配置:
编译主webpack文件,自动加入dll.js以及main.js
下图是页面引入dll依赖以及引入主js:
接下来讲解如何实现。
webpack_dll.config.js负责构建dll.js,在项目中把react的基本依赖库打包成react.dll.js,
把常用的polyfill打包成polyfill.dll.js。这两个需要在index.html引入。在webpack主配置中利用DllReferencePlugin插件根据对应名字的json文件,json文件会根据id与路径,引入打包好的dll文件。并且在main.js中不会出现dll重复打包的模块(react等配置进去的模块不会再次打包如main.js),减少主要js的体积,提高构建速度。
执行构建时,首先要编译webpack_Dll.config.js,构建出配置的dll,然后再编译webpack的主配置,编译出main.js,然后引入dll系列js,最后引入main.js。
由于动态链接库大多数包含的是常用的第三方库,一般都不会随意升级,在package.json的依赖上删除^标示。当涉及dll的库升级,或者添加第三方库,就需要重新编译了。
三. 使用HappyPack
HappyPack 是通过把loader交给程序多进程去并发处理,由于js是单线程,只能通过多进程去发挥cpu的功能。配置也相对简单。
四. 使用Tree Shaking
TreeShaking可以用来提出javascript中用不上的死代码.它依赖静态的ES6模块化语法。Webpack2.0版本经已内置。从一简单例子解释Tree Shaking的作用。假如有一个文件util.js里存有两函数。在main.js引入和使用util.js
util.js源码如下export function funcA(){<br/>}<br/>export function funcB() {<br/>}<br/>
main.js源码如下import { funcA } from ‘./util.js‘ funcA()
经过TreeShaking后 util中funcB函数没有被引入使用就会被TreeShaking当作死代码剔除。
接下来讲解如何配置Webpack让Tree Shaking,以react项目为例子。
首先修改babel的规则presets: [["env, { modules: false }"], ‘react‘, ‘statge-0‘]
其中modules: false的含义是关闭Babel的模块转换功能,保留原本的ES6模块化语句。
修改第三方库的引入文件规则
以redux为例子,其发布到Npm上的目录结构为:
|-- es
---- index.js
|-- lib
---- index.js
package.json
在package.json有两个字段
"main": "lib/index.js", // 采用commonJs模块化入口
"jsnext:main": "es/index.js", // 采用es6模块化入口
以下配置的含义优先使用jsnext:main作为入口,即采用es6模块化入口代码。
modules.exports = {
resolve: {
mainFields: [‘jsnext:main‘, ‘browser‘, ‘main‘],
},
}
然后配合UglifyJS插件处理一遍代码,即可剔除死代码,提高构建速度。
如出现当前问题只需npm install babel-preset-env -D安装babel-preset-env依赖即可。
五.使用ParalleUglifyPlugin
ParalleUglifyPlugin采用多进程压缩代码,每个进程还是通过UglifyPlugin去压缩代码。
更多参数配置详见https://www.npmjs.com/package/webpack-parallel-uglify-plugin
以上是关于webpack性能优化总结的主要内容,如果未能解决你的问题,请参考以下文章