当前位置:科技动态 > 性能优化---Webpack构建速度优化

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

  • 发布:2023-10-06 12:29

如何输出Webpack构建分析 输出Webpack构建信息的.json文件:webpack --profile --json >starts.json --profile:记录构建过程中的耗时信息 --json:以json格式输出构建结果,仅输出一个json文件(包含所有构建信息) Web可视化查看构建分析:我拿到了webpack构建信息文件starts.json,如何做好可视化查看? ​ 1.选项一:使用可视化分析工具Webpack Analyse,这是一个在线Web应用程序。只需上传starts.json文件即可; 2.选项2:安装webpack-bundle-analyzer工具npm i -g webpack-bundle-analyzer。生成starts.json后,直接在其文件夹目录下执行webpack-bundle-analyzer。浏览器将打开相应的网页并显示构建。分析文档地址 webpack-bundle-analyzer 3、webpack-dashboard是一个webpack日志统计和优化的工具。它可以以表格格式显示日志信息。这包括构建过程和状态、日志以及涉及的模块列表 4.jarvis是一个基于webapck-dashboard的webpack性能分析插件。性能分析结果在浏览器中展示,比webpack-bundler-anazlyer GitHub文档地址更美观、更清晰 npm i -D webpack-jarvis webpack.config.js 配置: const Jarvis = require("webpack-jarvis"); plugins: [ new Jarvis({ watchOnly: false, port: 3001 // 可选:设置端口 }) ]; port:监听端口,默认是1337,监控面板会监听这个端口,一般是http://localhost:port/Host:域名,默认为localhost,不限制域名。 watchOnly:只监视编译阶段。默认为 true。如果high值为false,jarvis不仅在编译阶段运行,而且在编译完成后仍保持运行状态。 界面:看到构建时间为:时间:11593ms(作为优化时间对比) webpack配置优化 webpack启动时,会从配置的Entry开始,解析出文件中的import语句,然后递归解析。 Webpack 会对 import 语句进行以下操作: ​​ 1.根据import语句找到对应的需要导入的文件; ​ 2.根据要导入的文件的后缀,使用配置中的Loader来处理文件(如果使用ES6,则需要使用babel-loader来处理) 基于这两点,可以优化搜索方法 1.优化Loader配置 Loader处理文件转换操作非常耗时,因此需要让Loader处理尽可能少的文件 { test: /\.js$/, use: [ 'babel-loader?cacheDirectory', // 启用转换结果缓存 ], include: path.resolve(__dirname, 'src'), // 仅限 src 目录下的文件使用babel-loader排除:path.resolve(__dirname,'./node_modules'),//排除node_modules目录下的文件 }, 2.优化resolve.modules配置 resolve.modules 用于配置 webpack 搜索第三方模块的目录。默认值为['node_modules']。不过,它会先去当前目录下的./node_modules进行搜索。如果没有,就会去../node_modules,最后去根目录。 ; 因此,当安装的第三方模块放在项目根目录下时,不需要通过默认的层层搜索,直接指明存储的绝对位置。 解析:{            模块:[path.resolve(__dirname, 'node_modules')],                                                                     ;3.优化resolve.extensions配置 当导入不带文件后缀的路径时,webpack会自动添加后缀来尝试询问文件是否存在,resolve.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构建动态链接库const 路径 = require('路径'); const DllPlugin = require('webpack/lib/DllPlugin'); module.exports = { mode: 'product',entry: { // 将React相关模块放入动态链接库react: ['react','react-dom','react-router-dom','react-loadable '],   librarys: ['wangeditor'],    utils: ['axios','js-cookie']  } , 输出: {FILENAME: '[name] -dll.js', Path: Path.Resolve (__diRNAME, ' DLL'), // 动态链接库的全局变量名,加_dll_防止全局变量冲突 库library library : '_dll_[name]' }, // 动态链接库的全局变量名需要与output.library一致,也是输出manifest.json文件中name的字段值 // 如react.manifest.json字段中存在 "name":"_dll_react" plugins: [ new DllPlugin({ name : '_dll_[名称]', 路径: path.join(__dirname, 'dll', '[名称].manifest.json') 在 webpack.pro.config.js 中使用const dllreferencenenceplugin = Require ('Webpack/Lib/DLLREFERENCENCELUGIN'); ... Plugins: [//告诉Webpack是哪个动态链接库 NEW DLLREFERENCENCEPLUGIN({Manifest: Require (Require (Require (Require('./dll/react.manifest.json')) }), new DllReferencePlugin({ manifest : require('./dll/librarys.manifest.json') }), new DllReferencePlugin({ 清单: require re('./dll/utils.manifest.json') }), ] 注意:webpack_dll.config.js文件中,DllPlugin中的name参数必须与output.library中的name参数保持一致;因为DllPlugin的name参数影响输出manifest.json的名称;而 webpack.pro.config.js 中的 DllReferencePlugin 会在从全局变量获取动态链接库内容时读取manifest.json的名称,并将该值作为全局变量名称。 执行构建 ​ 1. webpack --progress --colors --config ./webpack.dll.config.js 2. webpack --progress --colors --config ./webpack.prod.js 将dll.js文件引入html中 构建时间比较:[“11593ms”,“10654ms”,“8334ms”] HappyPack 并行构建优化 核心原理:将webpack中最耗时的loader文件转换操作任务分解为多个进程并行处理,从而减少构建时间。 快乐包 接入快乐包1.安装:npm i -D happypack 2、重新配置rules部分,将loader交给happypack进行分发:const HappyPack = require('happypack'); const happyThreadPool = HappyPack.ThreadPool({size: 5}); //构建共享进程池,包含5个进程 ...plugins: [ // happypack并行处理 new HappyPack({ //用ID表示当前HappyPack用于处理特定类型的文件,对应use in Rules id: 'babel', loaders: ['babel-loader?cacheDirectory'], //默认设置loader处理 threadPool: happyThreadPool,//使用共享池处理 }), new HappyPack({ 使用唯一的ID来表示目前的HappyPack,它是用来处理特定类型的文件的,对应规则中使用id:'css',loaders:['css-loader','postcss-loader','sass-loader'],ThreadPool: HappythreadPool})],模块:{规则:[{测试:/\。 (js|jsx) $/, 使用: [' happypapa CK /loader?id=babel'],                  排除: path.resolve(__dirname,' ./node_modules'),                                                                                                                                                                                                                                           。该插件在这里提取 css。如果放在上面就会出错。使用:[MiniCssExtractPlugin.loader,'happypack/loa德? ID = css'], 包含: [Path.Resolve(__ DIRNAME, 'SRC'), PATH.JOIN(__ DIRNAME, './Node_modules/antd')]}, } 参数: } 参数: ​​ 1.Threads:代表启动多少个子进程来处理该类型文件,默认为3; ​ 2. verbose:是否运行HappyPack输出日志,默认为true; 3、threadPool:代表共享进程池,即多个HappyPack实例使用共享进程池中的子进程来处理任务,防止资源占用过多 代码压缩使用ParallelUglifyPlugin而不是内置的UglifyJsPlugin插件 内置的JS压缩插件是单线程执行的,而webpack-parallel-uglify-plugin可以并行执行。 配置参数: ​ 1.uglifyJS:{}:用于压缩ES5代码时的配置,Object类型 ​ 2.测试:/.js$/g:使用正则表达式匹配哪些文件需要ParallelUglifyPlugin压缩。默认为/.js$/ 3.include:[]:使用正则表达式包含压缩文件,默认为[]。 ​​ 4.排除:[]:使用正则表达式包含未压缩的文件。默认为[] ​​5.cacheDir: '':缓存压缩结果。下次遇到相同的输入时,直接从缓存中获取压缩结果并返回。默认情况下不会被缓存。打开缓存并设置目录路径。 ​​ 6.workerCount: '':启动多个子进程并发进行压缩。默认为当前运行计算机的CPU核心数减1 ​​7.sourceMap: false:是否为压缩代码生成对应的Source Map,默认不生成...minimizer: [ // webpack:生产模式默认配备js压缩,但如果这里设置了css压缩,js压缩也必须重新设置,因为使用minimizer会自动取消webpack的默认配置 new optimizeCssPlugin({ assetNameRegExp: /\.css $/g, CSSPROCESSOR: Require ('CSSNANO'), CSSPROCESSOROPTIONS: {DiscardComments: {Removeal: True}, CanPrint: True}), 新的 ParalleLugli fyplugin ({cachedir: '.cache/', uglifyjs : { OUTPUT: {// 输出是否是更具可读性的代码,即会保留空格和组件,默认是输出,为了达到更好的压缩效果,可以设置为False Beautify: False , // 是否保留代码中的注释,默认是保留,为了达到更好的压缩效果,可以设置为 false comments: false warnings: false, //是否删除代码中所有控制台语句,默认不删除,开启后,所有控制台语句都会被删除      drop_console: true,   //是否嵌入已经定义但只使用一次的变量,如var x = 1; y = x,转换为y = 1,默认为无collapse_vars: true,}}}),]构建结果对比:["11593ms","10654ms","8334ms","7734ms"] 整体构建速度从 12000ms 下降到目前的 8000ms “迈小步,行千里”——持续更新~喜欢就点赞关注吧! 往期经典文章: 你不知道的CORS跨域资源共享 Koa日志中间件封装开发(log4js) 团队合作的基本 Git 操作 使用pm2部署node生产环境

相关文章