当前位置: 首页 > Web前端 > CSS

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

时间:2023-03-31 02:15:17 CSS

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