浅谈Vue SPA 首屏加载优化实践


Posted in Javascript onDecember 15, 2017

写在前面

本文记录笔者在Vue SPA项目首屏加载优化过程中遇到的一些坑及优化方案!

我们以 vue-cli 工具为例,使用 vue-router 搭建SPA应用,UI框架选用 element-ui , ajax方案选用 axios, 并引入vuex ,使用 vuex-router-sync 将 router 同步到 store ,服务器使用本地Nginx服务。

构建项目

vue-init webpack vue-spa-starter-kit
cd vue-spa-starter-kit
npm install
npm install vuex element-ui axios -S
npm run dev

vue-cli会自动打开浏览器,可以看到效果。我们在入口文件中引入vue-router、element-ui、axios

// src/main.js
import 'babel-polyfill'
import Vue from 'vue'
import App from './App'
import axios from 'axios'
import store from './store'
import router from './router'
import {sync} from 'vuex-router-sync'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.config.productionTip = false

Vue.use(ElementUI)
Vue.prototype.$http = axios

sync(store, router)

/* eslint-disable no-new */
new Vue({
 el: '#app',
 store,
 router,
 template: '<App/>',
 components: { App }
})

接下来我们不做任何修改,使用默认的配置进行打包,Nginx采用默认配置,部署到Nginx,启动Nginx服务,查看效果:

浅谈Vue SPA 首屏加载优化实践

可以看出,在没有开发任何页面及功能的情况下,vendor.js 有788kb。如果我们再依赖一些其他的库,比如 echarts 等,vendor.js 能到 1M 以上。

使用CDN资源

我们要将 vue、 vue-router、 vuex、element-ui 从 vendor.js 中分离出来,使用CDN资源引入。国内的CDN服务推荐使用 BootCDN。国外不是很好用。。。

首先在模板文件index.html中添加以下内容:

...
<head>
 <link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.0.7/theme-chalk/index.css" rel="external nofollow" >
</head>
<body>
 <div id="app"></div>
 <script src="https://cdn.bootcss.com/vue/2.5.9/vue.min.js"></script>
 <script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script>
 <script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
 <script src="https://cdn.bootcss.com/element-ui/2.0.7/index.js"></script>
 <!-- built files will be auto injected -->
</body>

修改 build/webpack.base.conf.js。关于 externals 配置项请自行查阅相关资料。

module.exports = {
 ...
 externals: {
  'vue': 'Vue',
  'vuex': 'Vuex',
  'vue-router': 'VueRouter',
  'element-ui': 'ElementUI'
 }
 ...
}

修改 src/router/index.js

// import Vue from 'vue'
import VueRouter from 'vue-router'
// 注释掉
// Vue.use(VueRouter)
...

修改 src/store/index.js

...
// 注释掉
// Vue.use(Vuex)
...

修改 src/main.js

import 'babel-polyfill'
import Vue from 'vue'
import App from './App'
import axios from 'axios'
import store from './store'
import router from './router'
import {sync} from 'vuex-router-sync'
import ELEMENT from 'element-ui'
// import 'element-ui/lib/theme-chalk/index.css'

Vue.config.productionTip = false

Vue.use(ELEMENT)
Vue.prototype.$http = axios

sync(store, router)

/* eslint-disable no-new */
new Vue({
 el: '#app',
 store,
 router,
 template: '<App/>',
 components: { App }
})

注意!这里 element-ui 变量名要使用 ELEMENT,因为element-ui的 umd 模块名是 ELEMENT

再次打包,部署到Nginx服务,可以看到:

浅谈Vue SPA 首屏加载优化实践

vendor.js 减少到了 112kb,提升85.5%!

再看CDN资源:

浅谈Vue SPA 首屏加载优化实践

可以看出,5个请求共216kb,耗时619ms!

Nginx 开启 gzip

对 vendor.js 我们优化完了,接下来我们优化服务器上的资源。先看看没有开启 gzip 的效果:

浅谈Vue SPA 首屏加载优化实践

可以看到有 13.5kb

Nginx开启gzip,修改nginx配置文件 nginx.conf:

...
http {
  ...
  gzip        on;
  gzip_min_length  1k;
  gzip_buffers    4 16k;
  #gzip_http_version 1.1;
  gzip_comp_level  2; # 压缩级别
  # 要压缩的mine类型
  gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss image/jpeg image/gif image/png image/svg+xml;
  gzip_vary     off;
  gzip_proxied    expired no-cache no-store private auth;
  gzip_disable    "MSIE [1-6]\."; # IE6不支持gzip
  ...
}

关于 nginx gzip,请自行查阅相关资料

重启nginx服务,再看效果:

浅谈Vue SPA 首屏加载优化实践

可以看到服务器上的资源经过gzip压缩之后有 9kb,压缩比 13.3%。

总结

至此,我们初步的优化就完成了。我实际的项目首屏加载从 12s 左右优化到 4s 左右。由于是演示项目,并没有开发其他的页面和功能,效果不是很明显,大家可以自行踩坑。大家有更好的方案,可以共同学习!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
setInterval,setTimeout与jquery混用的问题
Apr 08 Javascript
jquery删除ID为sNews的tr元素的内容
Apr 10 Javascript
Firefox下无法正常显示年份的解决方法
Sep 04 Javascript
浅谈JavaScript正则表达式分组匹配
Apr 10 Javascript
javascript类型系统 Array对象学习笔记
Jan 09 Javascript
理解javascript定时器中的单线程
Feb 23 Javascript
Bootstrap学习笔记之环境配置(1)
Dec 07 Javascript
对vue下点击事件传参和不传参的区别详解
Sep 15 Javascript
Vue发布项目实例讲解
Jul 17 Javascript
vue iview的菜单组件Mune 点击不高亮的解决方案
Nov 01 Javascript
ES6 proxy和reflect的使用方法与应用实例分析
Feb 15 Javascript
JavaScript实现简单日历效果
Sep 11 Javascript
利用VS Code开发你的第一个AngularJS 2应用程序
Dec 15 #Javascript
Angular2开发环境搭建教程之VS Code
Dec 15 #Javascript
JavaScript原生实现观察者模式的示例
Dec 15 #Javascript
基于javascript 显式转换与隐式转换(详解)
Dec 15 #Javascript
ReactNative中使用Redux架构总结
Dec 15 #Javascript
Angular中使用MathJax遇到的一些问题
Dec 15 #Javascript
vue实现验证码输入框组件
Dec 14 #Javascript
You might like
Drupal 添加模块出现莫名其妙的错误的解决方法(往往出现在模块较多时)
2011/04/18 PHP
浅谈laravel-admin form中的数据,在提交后,保存前,获取并进行编辑
2019/10/21 PHP
JQuery 学习笔记 选择器之一
2009/07/23 Javascript
chrome不支持form.submit的解决方案
2015/04/28 Javascript
JavaScript操作Cookie方法实例分析
2015/05/27 Javascript
jQuery实现带滑动条的菜单效果代码
2015/08/26 Javascript
jquery验证邮箱格式并显示提交按钮
2015/11/07 Javascript
详解JavaScript for循环中发送AJAX请求问题
2020/06/23 Javascript
BootStrap和jQuery相结合实现可编辑表格
2016/04/21 Javascript
值得分享和收藏的Bootstrap学习教程
2016/05/12 Javascript
Node.js的环境安装配置(使用nvm方式)
2016/10/11 Javascript
基于jQuery实现顶部导航栏功能
2016/12/27 Javascript
javascript判断元素存在和判断元素存在于实时的dom中的方法
2017/01/17 Javascript
Vue2.x中的Render函数详解
2017/05/30 Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
小程序实现发表评论功能
2018/07/06 Javascript
vue click.stop阻止点击事件继续传播的方法
2018/09/04 Javascript
js实现按钮开关单机下拉菜单效果
2018/11/22 Javascript
jQuery设置下拉框显示与隐藏效果的方法分析
2019/09/15 jQuery
vue setInterval 定时器失效的解决方式
2020/07/30 Javascript
解决Element中el-date-picker组件不回填的情况
2020/11/07 Javascript
python实现文件分组复制到不同目录的例子
2014/06/04 Python
为Python的web框架编写MVC配置来使其运行的教程
2015/04/30 Python
Python中pygame安装方法图文详解
2015/11/11 Python
代码分析Python地图坐标转换
2018/02/08 Python
浅谈python3.x pool.map()方法的实质
2019/01/16 Python
pandas计数 value_counts()的使用
2019/06/24 Python
Python使用grequests(gevent+requests)并发发送请求过程解析
2019/09/25 Python
pytorch之添加BN的实现
2020/01/06 Python
Python插件机制实现详解
2020/05/04 Python
中学生在校期间的自我评价分享
2013/11/13 职场文书
致1500米运动员广播稿
2014/02/07 职场文书
授权委托书公证
2014/09/14 职场文书
干部个人考察材料
2014/12/24 职场文书
公司辞职信模板
2015/05/13 职场文书
2019年最新借条范本!
2019/07/08 职场文书