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

【宝珍】我的第一次webpack优化,首屏渲染从9s到1s

时间:2023-03-28 00:57:28 HTML

大家好,我是毛小白,本文基于vue2,阅读全文大概需要3分钟。说到webpack优化,可能大部分人都看腻了。这只是一些技巧。之前看过很多类似的文章,但是自己并没有真正尝试过。下面是我在公司的项目中实际实践过的。首屏加载速度大幅提升(滑动),希望对您有所帮助。废话不多说,先来看看对比结果吧!类型优化前和优化后的js文件大小为24MB3MB。首页第一屏显示9s1s。这简直太夸张了,增加了8倍?可以想象之前有多慢,等了很久。漫王,真汉子,已经开过两次游戏了~可以看到优化前后首屏加载速度都有所提升。我一直想优化我们项目首屏的加载时间。有缓存还好,没有缓存就白屏了。等待7或8秒。尤其是对于一些第一次开机的客户来说,那7、8秒仿佛过了一个??世纪,非常尴尬。那我做了哪些常规操作呢?1.关闭生产环境中的productionSourceMap和csssourceMap。众所周知,当页面出现某些错误时,SourceMap可以定位到特定的代码行。SourceMap就是帮你建立这个映射关系,方便代码调试。在生产环境中,我们根本不需要开启这个功能(谁在调试生产环境的代码?又不是你),配置如下:constisProduction=process.env.NODE_ENV==='production'//判断是否为生产环境module.exports={productionSourceMap:!isProduction,//关闭生产环境中的SourceMap映射文件css:{sourceMap:!isProduction,//csssourceMap配置loaderOptions:{...othercode}},...othercode}here当你再次运行npmrunbuild打包时,你会发现速度快了很多,体积瞬间就只有几兆了!2.分析大文件,找出内鬼。安装npminstallwebpack-bundle-analyzer-D插件。打包后会产生一个本地服务,清楚的显示打包文件的包含关系和大小。vue.config.jsconfiguration:constBundleAnalyzerPlugin=require('webpack-bundle-analyzer').BundleAnalyzerPluginmodule.exports={...OtherconfigureWebpack:[plugins:[newBundleAnalyzerPlugin()//使用默认配置分析包大小]},...Others}自动弹出一个服务,清楚的显示打包后的js文件大小:从图中可以发现element-ui和ant-design占了近1/4的大小:1.53MB。exceljs也是个大东西:1.3MBBecharts.js文件也接近1MBmoment.js也有700KB。打包后js文件一共只有5MB,这五个哥们占了4M左右。不分析还好,一分析就毛骨悚然~别虚伪!找到刺后,将它们一根一根地拔掉。相信我,拔掉插头的过程非常爽。一一解决,拔掉荆棘1.必须用到的第三方js通过cdn的方式参考分析,发现必须用到elementui和echarts,而且打包比较费时,页面加载也很慢。可以直接通过CDN导入,方便快捷。1.element-ui是我们项目中使用的主要框架,所以这个肯定是少不了的,但是为什么项目中会有ant-design呢?原来有一个页面使用了antd的进度条组件,因为elementui的进度条不是那么漂亮。但是没想到这样导入了整个antd。解决办法:放弃antd组件,找一个类似的vue插件或者干脆自己实现一个。(这个方法短时间内无法完成,又不想触及之前的代码,所以暂时不考虑)使用antd进行部分加载。只加载需要的进度条组件可以减小文件大小(这种方法简单粗暴,就是牺牲一些文件大小)。我们按照antd官方文档使用方案2来配置一些组件的引入。安装npminstallbabel-plugin-import-D1main.jsimportrequiredcomponentsStepimport{Steps}from'ant-design-vue';Vue.component(Steps.name,Steps);Vue.component(Steps.Step.name,Steps.Step);2babel.config.js加上配置:module.exports={presets:['@vue/cli-plugin-babel/preset'],//下面是按需加载的配置+++++plugins:[["import",{libraryName:"ant-design-vue",libraryDirectory:"es",style:true}]]}现在再分析一下,antd已经小了很多。2.使用CDN加载第三方js。我们项目中有很多第三方js,有的打包的时候会很大,加载速度慢。我们将这些js分离出来,通过CDN直接在html中的script标签中使用。一方面减少了包装体积,另一方面提高了装载速度。这里推荐一个免费的cdn:BootCDN。您也可以使用自己购买的付费CDN服务。我们去网站搜索我们项目需要的js。比如:注意vue,一定要选择自己项目对应的版本,不然会出现各种奇怪的问题我的项目使用的是"vue":"^2.6.12",(package.json)第一步:配置vue。config.js,让webpack不打包这些js,而是通过script标签添加。constisProduction=process.env.NODE_ENV==='production'//判断是否为生产环境//官方环境不打包publicjsletexternals={}//存放cdn的文件letcdn={css:['https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.0/theme-chalk/index.min.css'//element-uicss样式表],js:[]}//必填只针对官方环境if(isProduction){externals={//排除打包好的jsvue:'Vue','element-ui':'ELEMENT',echarts:'echarts',}cdn.js=['https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js',//vuejs'https://cdn.bootcdn.net/ajax/libs/element-ui/2.6.0/index.js',//element-uijs'https://cdn.bootcdn.net/ajax/libs/element-ui/2.6.0/locale/zh-CN.min.js','https://cdn.bootcdn。net/ajax/libs/echarts/5.1.2/echarts.min.js',]}module.exports={//...其他配置configureWebpack:{//常用的publicjs排除,不打包但在index中addcdn,externals,//...其他配置},chainWebpack:config=>{//...其他配置//注入cdn变量(打包时会执行)config.plugin('html').tap(args=>{args[0].cdn=cdn//为插件配置cdnreturnargs})}//...其他配置}第二步:将定义的cdn变量添加到html模板代码中使用<元名称="viewport"content="width=device-width,initial-scale=1.0">webfavicon.ico"><%for(varcssofhtmlWebpackPlugin.options.cdn.css){%>"><%}%><%for(varjsofhtmlWebpackPlugin.options.cdn.js){%><%}%>gt;

大家可以发现,在cdn.js中,我加入了vue、echarts、element-ui的三大头。externals对象左边是npm包的名称,右边是代码中暴露的全局变量。注意element-ui对应于ELEMENT。没有ant-design-vue是因为我们使用了上面的部分加载方式。如果用cdn的话,这种方法是加载所有的代码,有点浪费。我没有使用exceljs,因为我的业务代码中并没有直接引用exceljs,而是间接依赖了table2excel。所以即使我通过上面的方法排除,打包的时候还是会通过table2excel的依赖找到并打包。如何优化这种不可避免的情况,使加载速度不受影响?答案是通过延迟加载:1.注释掉script标签中的importTable2Excelfrom"table2excel.js";2、下载方法中:download(){//使用import().then()方法import("table2excel.js").then((Table2Excel)=>{newTable2Excel.default("#table").export('filename')//加一层default})}这样在进入系统的时候就不会加载Table2Excel和exceljs了,需要的时候再加载。第一次会比较慢,后面不用加载,会比较快。3moment.js的优化我们发现项目中使用了monentjs来格式化时间,但是使用频率并不高。你可以自己实现一个格式化方法,或者只使用6kbday.js。但是我们这里不替换,只是把moment变细,删除除中文以外的语言包。第一步:vue.config.js...其他配置chainWebpack:config=>{config.plugin('ignore')//忽略/moment/locale.use(newwebpack.IgnorePlugin(/^\.\/locale$/,/moment$/))}...其他配置第二步:main.jsimportmomentfrom'moment'//手动导入需要的语言包import'moment/locale/zh-cn';//指定使用的语言moment.locale('zh-cn');这一次,让我们看看moment打包后有多大:只有174kb。不过,有一点要说的是day.js还是很好吃的~做了以上操作后,我们的js文件总大小:3.04MB,其中懒加载js1.3MB,剩下的1.7MB左右的js会基本不会对页面造成损坏。大纸箱。有改进的余地吗?1.通过compression-webpack-plugin插件将代码压缩成gzip。但!服务端需要支持webpack端vue.config.js配置如下://打包压缩静态文件插件constCompressionPlugin=require("compression-webpack-plugin")//...其他配置module.exports={//...其他配置chainWebpack:config=>{//在生产环境启用js\css压缩if(isProduction){config.plugin('compressionPlugin').use(newCompressionPlugin({test:/\.(js)$/,//匹配文件名阈值:10240,//压缩超过10k的数据minRatio:0.8,deleteOriginalAssets:true//删除源文件}))}}//...其他配置}包大小从3MB到860KB,感觉起飞了~服务器端的配置这里就不详细说了。谷歌一下就可以找到答案:nginxenablestaticcompression。最后贴上优化前后无缓存首屏加载时间对比(chrome浏览器),绝对真实:项目网站优化前首屏加载数据:9.17s和的加载数据项目网站优化后首屏:1.24s这些都是闲暇之余,抽空看看大佬们的帖子。虽然都是比较牛逼的技术,但是在自己的项目中实现起来还是需要一些时间和精力的。大多数都是为了快速完成功能。迭代忽略了做程序的初衷是为了让用户有好的体验。请大家不要忘记点赞、评论、收藏我。往期亮点:1.什么是迭代器?Generator和它有什么关系?2、微信小程序UI组件、图表、自定义栏都是你踩的坑