当前位置: 首页 > Web前端 > vue.js

如何将vue项目的启动时间从70s优化到7秒?

时间:2023-04-01 11:00:20 vue.js

惨不忍睹的启动时间公司的产品是一个比较大的后台管理系统,使用的是webpack3的vue模板项目,单个项目的启动时间达到启动一个项目70s左右就够吃一碗豆腐了脑残,但是没有豆腐脑怎么办,那就优化启动时间吧!考虑到升级webpack版本的风险还是比较高的,有什么问题可以来找我。想一想,不冒险,以安全为重,所以选择了通过插件来优化构建时间。通过查阅资料,提高webpack构建时间有几个方向:多进程处理文件,同时处理多个文件预编译资源模块,比如提取长期不变的库进行预编译,以及构建时直接取编译结果易于缓存,未修改的模块直接获取处理结果,无需编译,减少查找和处理文件的数量。针对以上优化方向,给出如下优化方案。多进程构建happypackhappypack的作用是将文件解析任务分解成多个子进程并发执行。子进程处理完任务后,将结果发送给主进程。所以它可以大大提高Webpack的项目组件的速度。查看happypack的github,发现作者不再维护插件,作者推荐使用webpack官方的多进程插件thread-loader,于是放弃了happypacy,选择了thread-loader。thread-loaderthread-loader是一个官方维护的多进程加载器。它的功能类似于happypack。它还通过打开子任务并行解析文件,从而提高构建速度。将此装载机放在其他装载机的前面。但是,装载机是有限的。示例:加载程序未能发出文件。加载程序不能使用自定义加载程序API。加载程序无法访问webpack选项。每个worker都是一个单独的node.js进程,开销约为600ms。还有进程间通信的开销。在小项目中使用thread-loader可能不会优化项目的构建速度,反而会拖慢构建速度。所以在使用这个loader的时候,一定要搞清楚工程构建中真正耗时的过程。在我的项目中,我主要使用这个loader来解析vue和js文件,作用于vue-loader和babel-loader,代码如下:constthreadLoader={loader:'thread-loader',options:{workers:require('os').cpus().length-1,}}module.exports={module:{rules:[{test:/\.vue$/,use:[threadLoader,//在vue-loader之前使用这个加载器{loader:'vue-loader',options:vueLoaderConfig}],},{test:/\.js$/,use:[threadLoader,//在babel-loader之前使用这个加载器{loader:'babel-loader',options:{cacheDirectory:true}}]}]}}复制代码并配置thread-loader后,尝试重建,如下图,构建时间缩短了10秒左右,还不错。使用缓存来提高二次构建的速度。虽然使用多进程构建项目缩短了10秒的构建时间,但是一分钟的构建时间还是让人难以接受。这种像挤牙膏一样的优化方式,有些让人不舒服。有没有一种很酷的方法可以进一步减少构建时间?答案是肯定的,使用缓存。缓存,不难理解,就是在第一次构建的时候缓存构建的结果。第二次构建时,检查相应的缓存是否被修改。如果没有,则直接使用缓存。由此,我们可以想象,当项目变化不大的时候,大部分的缓存都是可以复用的。岂不是建设速度有了质的飞跃?cache-loader说到缓存,当然百度一下,第一个出现的就是cache-loader。在github上搜索官方文档,得到如下结果:这个loader会缓存其他loader的处理结果,把这个loader放在其他loader的前面,同时这个loader也会有保存和处理的开销读取缓存文件,因此建议在开销较高的加载程序之前使用此加载程序。该文档非常简单。考虑到项目中的vue-loader、babel-loader、css-loader会有比较大的开销,所以给这些loader添加cache,然后在项目中添加cache-loader:constcacheLoader={loader:'cache-loader'}constthreadLoader={loader:'thread-loader',options:{workers:require('os').cpus().length-1,}}module.exports={module:{规则:[{test:/\.vue$/,use:[cacheLoader,threadLoader,//在vue-loader{loader:'vue-loader',options:vueLoaderConfig}],},{test:/\.js$/,use:[cacheLoader,threadLoader,//usethisloaderbeforebabel-loader{loader:'babel-loader',options:{cacheDirectory:true}}]}]}}将代码复制到util.js文件中,这个文件是主要是生成css相关的webpack配置,找到generateLoaders函数,修改如下:constcacheLoader={loader:'cache-loader'}functiongenerateLoaders(loader,loaderOptions){//在css-loader中添加cache-loader在constloaders=options.usePostCSS之前?[cacheLoader,cssLoader,postcssLoader]:[cacheLoader,cssLoaderr]if(loader){loaders.push({loader:loader+'-loader',options:Object.assign({},loaderOptions,{sourceMap:options.sourceMap})})}//当那个选项时提取CSS指定//(生产构建时就是这样)if(options.extract){returnExtractTextPlugin.extract({use:loaders,fallback:'vue-style-loader',//添加这个配置来解决element-ui图标路径问题publicPath:'../../'})}else{return['vue-style-loader'].concat(loaders)}}复制代码以上配置完成后,再次启动项目,可以发现,当前的启动时间没有变化,然后我们第二次启动项目,可以发现当前的启动时间已经达到了30s左右。之前我们说过,cache-loader缓存只会在第二次启动时生效。虽然项目启动时间已经优化了一大半,但是我们的愿望是无限的。30秒的时间和我们的预期还是有点距离。继续优化!hard-source-webpack-pluginHardSourceWebpackPlugin是一个webpack插件,为模块提供中间缓存步骤。为了看到结果,你需要用这个插件运行webpack两次:第一次构建将花费正常的时间。二期建设将大大加快。话不多说,直接配置到项目中:constHardSourceWebpackPlugin=require('hard-source-webpack-plugin');module.exports={//...plugins:[newHardSourceWebpackPlugin()]}把代码复制两遍在构建的时候,我们会发现构建时间已经到了个位数,只有短短的7秒。在第二次构建时,我发现一个现象,构建进度会从10%跳到80%,甚至中间的构建过程也是瞬间完成。这证实了插件为模块提供中间缓存的说法。为模块提供一个中间缓存,我的理解是cache-loader缓存对应loader的处理结果,而这个插件甚至可以缓存整个项目的所有处理结果,直接引用最终输出的缓存文件,从而大大提高构建速度。其他优化方法babel-loader开启缓存babel-loader自带缓存功能,开启cacheDirectory配置项即可。根据官方网站,启用缓存将增加转换时间大约两倍。module.exports={module:{rules:[{test:/\.js$/,use:[...{loader:'babel-loader',options:{cacheDirectory:true//启用缓存}}]}]}}复制代码uglifyjs-webpack-plugin启用多进程压缩uglifyjs-webpack-plugin或其他代码压缩工具提供多进程压缩代码的功能,可以加快代码压缩速度。综上所述,我们完成了项目构建时间从70s到7s的优化过程。本文主要使用:工具功能优化效果thread-loader多进程解析文件70s->60scache-loader缓存部分高开销加载器60s->30shard-source-webpack-plugin缓存模块中间进程30s->7s最后,如果您觉得本文对您有帮助,请点个赞。或者可以加入我的开发交流群:1025263163互相学习,我们会有专业的技术解答。如果您觉得这篇文章对您有用,请给我们的开源项目一个小星星:https://gitee。com/ZhongBangKe...非常感谢!