vue单页应用打包之后,渲染加载时由于是一次性加载整个应用,所以首次加载会特别慢,会出现长时间的白屏,极大影响用户体验,因此,我尝试了多种优化方法。

目录

1.按需加载

MintUI、ElementUI等UI框架都支持按需加载,直接在main.js内将需要用到的组件一一注册,或者只在需要用到的页面局部引用。

修改前:

main.js
1
2
3
4
import MintUI from 'mint-ui'
import 'mint-ui/lib/style.css'

Vue.use(MintUI)

修改后:

main.js
1
2
3
4
5
6
7
8
import { Popup, Picker, Spinner, Swipe, SwipeItem, Lazyload } from 'mint-ui'

Vue.use(Lazyload);
Vue.component(Popup.name, Popup);
Vue.component(Picker.name, Picker);
Vue.component(Spinner.name, Spinner);
Vue.component(Swipe.name, Swipe);
Vue.component(SwipeItem.name, SwipeItem);

2.异步组件

在路由定义中,将应用拆分为多个小模块,动态解析组件。

修改前:

router/index.js
1
2
3
4
5
6
7
8
9
import Index from '../views/index'

...
{
    path: '/index',
    name: 'Index',
    component: Index
}
...

修改后:

router/index.js
1
2
3
4
5
6
7
8
9
const Index = r => require.ensure([], () => r(require('../views/index')), 'Index')

...
{
    path: '/index',
    name: 'Index',
    component: Index
}
...

3.使用CDN

打包时,把vue、vuex、vue-router、axios等,换用国内的bootcdn 直接引入到根目录的index.html中。

在webpack设置中添加externals,忽略不需要打包的库。

build/webpack.prod.conf.js
1
2
3
4
5
6
7
8
...
externals: {
    'vue': 'Vue',
    'vuex': 'Vuex',
    'vue-router': 'VueRouter',
    'axios': 'axios'
  }
...
index.html
1
2
3
4
<script src="//cdn.bootcss.com/vue/2.2.5/vue.min.js"></script>  
<script src="//cdn.bootcss.com/vue-router/2.3.0/vue-router.min.js"></script>
<script src="//cdn.bootcss.com/vuex/2.2.1/vuex.min.js"></script>  
<script src="//cdn.bootcss.com/axios/0.15.3/axios.min.js"></script>

相应的,也就不需要import引用了,不然据说还是会打包进去(?这个没有深入研究对比过)

修改前:

store/index.js
1
2
3
4
5
6
7
8
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex)

//router/index.js
import Router from 'vue-router'
Vue.use(Router)

修改后:

store/index.js
1
2
3
4
5
6
7
8
9
10
11
//import Vue from 'vue';
//import Vuex from 'vuex';

if (process.env.NODE_ENV === 'development') {
    //开发环境没有的话会报错
    Vue.use(Vuex)
}

//router/index.js
//import Router from 'vue-router'
//Vue.use(Router)

4.在index.html页面加上loading,避免出现长时间的白屏状态

index.html
1
2
3
4
5
...
<div id="app">
//loading
</div>
...

当然,能实现骨架屏最好,还可以用SSR服务端渲染,但是挺复杂的,我没能实现

5.开启Gzip

gzip大约能减少20%的大小,不过需要服务端配合开启,服务端若开启了gzip,在Response Headers里可以看到Content-Encoding:gzip

在开启vue的gzip之前,需要先安装依赖compression-webpack-plugin,但是注意,默认的安装版本是2.0,可能是版本太高了,最后build的时候会报错,所以安装低版本的就可以了,即运行npm install --save-dev compression-webpack-plugin@1.1.11

然后

config/index.js
1
2
3
4
5
6
7
8
...
build:{
    ...
    productionGzip: true,
    productionGzipExtensions: ['js', 'css'],
    ...
}
...

6.图片懒加载

使用mint-ui中的Lazyload可实现。

以上就是我优化首屏加载速度的全部内容。