当前位置: 首页 > 科技观察

性能优化---webpack构建速度优化

时间:2023-03-20 15:43:45 科技观察

Webpack构建信息如何输出Webpack构建分析输出.json文件:webpack--profile--json>starts.json--profile:记录构建耗时信息--json:以json格式输出构建结果,只输出一个json文件(包含所有构建信息)web可视化视图构建分析:获取webpack构建信息文件starts.json,如何进行良好的可视化查看?1.方案一:使用可视化分析工具WebpackAnalyze,这是一款在线web应用,上传starts.json文件即可;2.方案二:安装webpack-bundle-analyzer工具npmi-gwebpack-bundle-analyzer生成starts。直接在其文件夹目录下执行webpack-bundle-analyzer,浏览器会打开相应的网页,并显示构建分析文件webpack-bundle-analyzer的地址3.webpack-dashboard是一个webpack日志统计和优化的工具,可以以表格的形式展示日志信息。它包括构建过程和状态、日志以及涉及的模块列表。4.jarvis是一个基于webapck-dashboard的webpack性能分析插件。性能分析结果显示在浏览器中,比webpack-bundler-anazlyer更加美观清晰。github文档地址npmi-Dwebpack-jarviswebpack.config.js配置:constJarvis=require("webpack-jarvis");plugins:[newJarvis({watchOnly:false,port:3001//optional:setaport})];port:listen端口,默认是1337,监控面板会监听这个端口,一般像http://localhost:port/host:域名,默认是localhost,不限制域名。watchOnly:只监听编译阶段。默认为true,如果high为false,jarvis不仅在编译阶段运行,编译完成后还会一直运行。界面:看到构建时间为:时间:11593ms(作为优化时间对比)webpack配置优化webpack在启动时会从配置的Entry开始,解析出文件中的import语句,然后递归解析。对于import语句,Webpack会做以下事情:1.根据import语句找到对应的要导入的文件;2.根据要导入的文件的后缀,使用配置中的Loader对文件进行处理(比如使用ES6需要使用babel-loader处理)针对这两点可以优化搜索路径1.优化Loader配置Loader处理文件转换比较耗时,所以要让Loader处理的文件尽可能少{test:/\.js$/,use:['babel-loader?cacheDirectory',//打开转换结果缓存],include:path.resolve(__dirname,'src'),//只对src目录下的文件使用babel-loaderExclude:path.resolve(__dirname,'./node_modules'),//排除文件在node_modules目录下},2.优化resolve.modules配置resolve.modules用于配置webpack会去哪些目录寻找第三方模块,默认是['node_modules'],但是它会先到./node_modules在当前目录下搜索,如果没有就去../node_modules,最后到根目录;所以当安装的第三方模块放在项目根目录时,不需要安装默认层层查找,直接指明存放的绝对位置resolve:{modules:[path.resolve(__dirname,'node_modules')],}3.优化resolve.extensions配置当导入没有文件后缀的路径时,webpack会自动带上后缀来尝试询问文件是否存在,resolve.extensions用于配置后缀列表来尝试;默认是extensions:['js','json'];而当遇到require('./data')时,webpack会先尝试寻找data.js,并没有再次寻找data.json;如果列表更长,或者正确的后缀更靠后,尝试的次数就会更多。因此,为了提高配置时的构建和优化,需要遵循:1.高频文件,将后缀放在前面;2.保持列表尽可能小;3、写import语句时尽量写后缀名由于项目中使用的jsx比较多,配置扩展名:[.jsx],".js"],基本配置后查看构建速度:时间:10654ms;配置前时间:11593ms使用DllPlugin优化,使用webpack打包有时,对于依赖的第三方库,如react、react-dom等未修改的依赖,可以与业务代码分开打包;只要依赖库的版本没有升级,那么webpack只需要打包项目业务代码即可。当需要导入的模块在动态链接库中时,直接获取即可;不用编译第三方库,第三方库只需要打包一次接入需要做的事情:1、将依赖的第三方模块提取出来,打包成单独的动态链接库2、当要导入的模块存在于动态链接库中时,让其直接从链接库中获取3.项目依赖的所有动态链接库都需要加载到接入工具中(webpack内置)1.DllPlugin插件:用于打包单个动态链接库文件;2.DllReferencePlugin:在主配置文件中使用引入DllPlugin插件打包动态链接库文件配置webpack_dll.config.js构建动态链接库constpath=require('path');constDllPlugin=require('webpack/lib/DllPlugin');module.exports={mode:'production',entry:{//将React相关模块放入动态链接库react:['react','react-dom','react-router-dom','react-loadable'],libraries:['wangeditor'],utils:['axios','js-cookie']},output:{filename:'[name]-dll.js',path:路径。resolve(__dirname,'dll'),//存放动态链接库的全局变量名,加上_dll_防止全局变量冲突library:'_dll_[name]'},//动态链接库的全局变量名output.library中需要保持一致,同时也是outputmanifest.json文件中name的字段值//例如"name":"_dll_react"plugins:[newDllPlugin({name:'_dll_[name]',path:path.join(__dirname,'dll','[name].manifest.json')})]}缺点tDllReferencePlugin=require('webpack/lib/DllReferencePlugin'inwebpack.pro.config.js);...plugins:[//告诉webpack使用了哪些动态链接库newDllReferencePlugin({manifest:require('./dll/react.manifest.json')}),newDllReferencePlugin({manifest:require('./dll/librarys.manifest.json')}),newDllReferencePlugin({manifest:require('./dll/utils.manifest.json')}),]注意:在webpack_dll.config.js文件中,DllPlugin中的名称参数必须与output.library中的一致;因为DllPlugin的name参数会影响输出manifest.json的名称;而webpack.pro.config.js中的DllReferencePlugin会读取manifest.json的名称,并将其值作为全局变量执行build1.webpack--progress获取动态链接库内容时的全局变量名--colors--config./webpack.dll.config.js2.webpack--progress--colors--config./webpack。prod.jshtml中介绍的dll.js文件构建时间对比:["11593ms","10654ms","8334ms"]HappyPack并行构建优化核心原理:将webpack中最耗时的loader文件转换操作任务分解成多个在一个进程中并行处理,从而减少构建时间将HappyPack连接到HappyPack1.安装:npmi-Dhappypack2.重新配置规则部分,将加载程序分配给happypack以进行分发:constHappyPack=require('happypack');consthappyThreadPool=HappyPack.ThreadPool({size:5});//构建共享进程池,包含5个进程...plugins:[//happypack并行处理newHappyPack({//使用ID表示当前HappyPack用于处理特定类型的文件,对应rules中的useid:'babel',loaders:['babel-loader?cacheDirectory'],//默认设置loader处理threadPool:happyThreadPool,//使用共享池处理}),newHappyPack({//使用唯一ID表示当前HappyPack用于处理特定类型的文件,对应规则中使用id:'css',loaders:['css-loader','postcss-loader','sass-loader'],threadPool:happyThreadPool})],module:{rules:[{test:/\.(js|jsx)$/,use:['happypack/loader?id=babel'],exclude:path.resolve(__dirname,'./node_modules'),},{test:/\.(scss|css)$/,//提取css用的mini-css-extract-plugin在这里,如果放在上面会报错use:[MiniCssExtractPlugin.loader,'happypack/loader?id=css'],include:[path.resolve(__dirname,'src'),path.join(__dirname,'./node_modules/antd')]},}参数:1.threads:表示开启若干个子进程来处理这一类文件,默认为3;2.verbose:是否运行HappyPack输出日志,默认为tr等;3.threadPool:表示共享进程池,即多个HappyPack实例使用共享进程池中的一个子进程处理任务,以防资源占用过多代码压缩使用ParallelUglifyPlugin代替自带的JS压缩UglifyJsPluginpluginPlugins是单线程执行的,而webpack-parallel-uglify-plugin可以并行执行配置参数:1.uglifyJS:{}:压缩ES5代码的配置,Object类型2.test:/.js$/g:使用正则匹配哪些文件需要被ParallelUglifyPlugin压缩,默认为/.js$/3.include:[]:使用正则包含压缩文件,默认为[]。4.exclude:[]:使用正则规则来包含未压缩的文件,默认为[]5.cacheDir:'':缓存压缩后的结果,下次遇到相同的输入时,直接从缓存中获取压缩后的结果并返回,默认不会缓存,开启Cache设置一个目录路径6.workerCount:'':开启多个子进程并发压缩默认为电脑当前运行的CPU核数减1。7.sourceMap:false:是否为压缩后的代码生成对应的SourceMap,默认不生成...minimizer:[//webpack:production模式默认带有js压缩,但是如果这里设置了css压缩,则必须重新设置js压缩,因为使用minimizer会自动取消webpack的默认配置newoptimizeCssPlugin({assetNameRegExp:/\.css$/g,cssProcessor:require('cssnano'),cssProcessorOptions:{discardComments:{removeAll:true}},canPrint:true}),newParallelUglifyPlugin({cacheDir:'.cache/',uglifyJS:{output:{//是否输出更具可读性的代码,即会保留空格和制表符,默认是输出,为了达到更好的压缩效果,可以设置为falsebeautify:false,//代码中是否保留注释,默认保留,在为了达到更好的压缩效果,可以设置为falsecomments:false},compress:{//UglifyJS删除不用的代码时是否输出警告信息,默认输出warnings:false,//是否删除代码中的所有控制台语句,默认不删除,打开后,会删除所有的console语句drop_console:true,//是否嵌入一个定义过但只使用过一次的变量,比如将varx=1;y=x转换成y=1,默认是nocollapse_vars:true,}}}),]构建结果对比:["11593ms","10654ms","8334ms","7734ms"]整体构建速度从12000ms下降到现在的8000ms“积步走万里”-持续更新~,喜欢就点赞关注吧!往期经典好文:你不知道的CORS跨域资源共享Koa日志中间件包开发(log4js)团队协作必备的git操作使用pm2部署node生产环境