记录一个前端项目优化的路程,效果如上图。
接下来我们在正文讲解具体优化步骤、思路以及优化前后对比,另外还有/static下文件被打包的解决方法。
PS:正文中图片模糊的话请右键“在新标签页打开图片”查看原图
WHY,为什么进行优化
本周在做的一个vue项目进入到测试阶段,在打包时候发现build耗时过长(近3分钟),觉得是有点异常,有过更复杂的项目但是耗时基本也在1分钟内,所以运行npm run build --report
生成打包的矩阵树图(Treemap)来进行排查,report截图如下:
发现项目中Location页面(用于数据可视化地理空间展示)的可视化功能所用到的几个国家map文件赫然出现在最前面,而项目打包后尺寸也达到了8.76M。
另外,在进入该页面时发现页面加载耗时明显增加(1.js有6.77M),说明页面渲染被堵塞。
HOW,如何进行优化
第一步,优化静态资源
分析后得出结论:map文件被打包到1.js中导致build和页面渲染时间增多。
接下来是优化思路:
- map文件基本不会动,所以可以压缩后放在/static中引入,减少build耗时
- 使用defer引入,解决页面渲染被堵塞的问题
static踩坑
因为项目使用vue-cli工具,此前记得文档中说静态资源放在/static中会直接copy而不进行打包
在把map文件直接移动到/static目录,还是会对这些文件进行打包,后面才想通:
资源放在/static不会被打包❌- 不打包的资源放在/static ✅
首先,/static目录下的资源需要使用绝对路径进行引入,比如img.src=”/static/xxx.png”;其次,在具体vue或js文件中使用import引入也是会被跟踪到并一起打包的。
所以最终是在index.html文件中直接使用script标签引入map资源,并使用defer方式避免堵塞页面正常渲染
1 | <script defer src="/static/map1.js"/> |
第一步优化结果
接下来看看优化效果:
可以看到现在打包后项目体积优化到2M。
此外,实际build时间也从3min减少到50s左右,Location页面渲染时间过长的问题也得到解决。
第二步,分离echarts
虽然项目体积已经锐减,但是个人对2M这个数字还不够满意,可以看到现在图中Treemap sizes显示最大的文件是vendor.js,vendor.js里面放着项目的一些依赖模块如vue、vue-route、axios、element-ui、echarts等,同时也可以看到现在最大的模块是echarts,所以接下来试着将echarts通过cdn的方式引入来达到减少项目体积的目的。
此处优化关键字:webpack externals,具体介绍见webpack文档 。我们可以简单理解为从cdn加载第三方模块,从而减少服务器压力和项目体积。
在/build/webpack.prod.conf.js文件中添加externals(vue-cli版本不同会有差异):1
2
3
4
5
6{
// other setting
externals: {
'echarts': 'echarts'
}
}
在index.html中使用script标签从cdn引入echarts1
2<script src="https://cdn.bootcss.com/echarts/4.1.0/echarts.min.js">
<div id="app"></div>
因为主要是一个可视化项目,用到echarts页面较多,所以这里在app之前就引入了。
通过externals方式分离echarts或其它模块,不用修改main.js里面的逻辑。
注1:也可以通过此种方式对其它模块如element-ui进行拆分
注2:针对echarts,也可以通过按需引入的方式达到优化效果。
第二步优化结果
再次运行npm run build --report
查看项目打包情况:
可以看到项目体积已经优化到1.26M,vendor.js中也看不到echarts的踪影了。
结语
至此本文结束,实际开发中各个项目的主要优化点都各不相同,需要在开发过程中一一发掘。
本文主要想提供一些优化思路及手段,即如何定位(通过build report,查看页面加载时间)问题,然后再解决这些问题。