记录:Vue移动端项目优化过程
文章目录
前言
最近在做项目时,测试提出了在App端的H5项目入口加载时间过长,白屏等待过久,需要优化的问题,于是着手开始分析:
- 项目技术栈:基于Vue全家桶做的一个移动端类似WebApp的项目,使用到的第三方库有:mint-ui, echarts,momentjs。
- 项目痛点:白屏时间过长
一、白屏时间过长分析
通过访问线上环境,结合Chrome devtool中Network和Performance功能可以具体分析整个白屏的耗时主要在哪一块儿
- Network耗时记录:
- Performance性能面板
- 通过上面两张图分析,从浏览器发起请求到解析HTML完成这一过程中:
-
animate.css, mini-ui.css
的请求耗时最长。 - 图片过大耗时。
二、针对性优化
针对animate.css
-
animate.css
由于使用的是第三方CDN(国外服务器)所有请求时间相对较长,所以如果必须要用animate.css那么可以下载下来作为本地资源,也可以使用国内CDN,或者不用animate.css,而是针对使用到的几个CSS动画,直接自己造*
针对mint-ui的优化
由于mint-ui在原项目中使用的是全局引用的方式,这才导致打包资源过大,css单独请求耗时过长的问题,所以主要解决方案是
按需引入mint-ui
,借助babel-plugin-component,
我们可以只引入需要的组件,以达到减小项目体积的目的。
- 安装babel-plugin-component, 若已安装可忽略
npm install babel-plugin-component -D
- 修改 .babelrc (重点在plugins中):
{
"presets": [
["env", { "modules": false }],
"stage-2"
],
"plugins": ["transform-runtime",["component", [
{
"libraryName": "mint-ui",
"style": true
}
]]],
"comments": false,
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": [ "istanbul" ]
}
}
}
- 在main.js中引用使用到的插件
import Vue from 'vue'
import { Button, Cell } from 'mint-ui'
import 'mint-ui/lib/style.min.css' // 引用CSS
import App from './App.vue'
Vue.component(Button.name, Button)
Vue.component(Cell.name, Cell)
/* 或写为
* Vue.use(Button)
* Vue.use(Cell)
*/
new Vue({
el: '#app',
components: { App }
})
- 在使用的组件中改为按需引用组件
import Vue from 'vue'
var Popup = Vue.component('mt-popup')
var Swipe = Vue.component('mt-swipe')
var SwipeItem = Vue.component('mt-swipe-item')
export default {
name:'my-component',
components:{
Popup,
Swipe,
SwipeItem
}
}
此按需引入方案也同样适用于其他第三方UI组件库
针对图片的优化
图片小图通过webpack可以直接转为base64,而大图可以通过压缩或者换格式的方式来优化,这里推荐一个好用的图片压缩工具,工具:tinyPNG,如下是图片转换前后对比
三、webpack打包优化与分析
在完成了上述优化以后,下面着重关注下webpack打包后生成的文件大小,看还有没有可以优化的余地。由于项目中已经通过
路由按需加载
的方式来做了功能拆分,所以通过webpack打包后生成了很多分散的js文件,如下图:
通过上图分析可以知道打包后有几个文件相对较大,vendor.js都知道是第三方库文件打包形成,之前通过mint-ui按需加载会有一定的变化,后面记录。这里着重看另两个带hash的js文件,这里并看不出来它为什么这么大,所以这里需要用到webpack打包分析工具来做进一步的打包文件分析:webpack-bundle-analyzer
webpack-bundle-analyzer打包分析
它的作用如下图,即在打包后生成打包文件大小分析图,方便我们更加直观的看到文件大小和引用情况
- 这里先介绍下webpack-bundle-analyzer的简单使用
- 安装
npm intall -D webpack-bundle-analyzer
- 修改
webpack.pro.conf.js
. (这里由于只是用于生产打包分析且是通过vue-cli生成的项目框架)
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
// ...
plugins:[
new BundleAnalyzerPlugin()
]
}
- 运行
npm run build
,(webpack默认会在打包完成时生成分析图)
打包优化
通过上面的分析图可以看到打包文件过大是由于第三方库引用的问题,如
mint-ui, moment.js, echarts.js,zrender,Vue
等
1. mint-ui按需加载改造
通过之前的按需引用加载后,再次webpack打包可以看到vendor.js中mint-ui
包的大小明显缩小
-
之前 95.31K
-
之后 34.96K
2. 第三方库引用优化-使用CDN
对于像Vue,Vue-router,echarts等都可以使用CDN的方式来引入,目前使用的是Bootcdn相对其他免费CDN还是比较稳定的
// 1. 在index.html中通过CDN方式引用第三方
<script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
// 2.修改webpack.base.conf.js
module.exports = {
// ...
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
},
}
- 优化后的vendor.js。从原来的
254.38K 压缩到了 69.56K
- 功能模块js的优化
通过分析图可以看到,剩下比较大的就是单文件js中引入了echarts.js, moment.js的包了,moment.js通过CDN引用方式也可以直接优化
而echarts.js由于项目中使用了一个第三方的组件库vue-charts
导致echarts被直接打包到了文件中,使用CDN的方式也无法把echarts抽离,这里采用的方式是重写图表组件,再使用CDN引入。
- 问题:
- 解决后,文件体积从201.75K降到了36.51K:
四、优化后线上测试速度提升
- Network优化后:
从发起到请求结束共350ms,相比于优化前的3.5s快了很多。总结:3.5s–>0.35s
- Performance面板:
通过performance可以看到整个过程从发起请求拿到index.html开始(3900ms处),到FMP位置(timestamp:4569.8 ms)结束,耗时约0.669s。总结:3.5s-> 0.669s
五、优化总结
此次优化大致用到以下几种方案:
- 路由按需加载
- mint-ui按需引入(配合
babel-plugin-component
缩小项目打包体积) - Vue,VueRouter,momentjs等使用CDN访问(配合webpack,externals)
- 图片压缩优化
- 公共代码抽离(这一步vue-cli其实已经在webpack中配置了CommonsChunkPlugin)