浅谈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 相关文章推荐
根据分辩率调用不同的CSS.
Jan 08 Javascript
通过Unicode转义序列来加密,按你说的可以算是混淆吧
May 06 Javascript
IE本地存储userdata的一个bug说明
Jul 01 Javascript
使用jQuery或者原生js实现鼠标滚动加载页面新数据
Mar 06 Javascript
javascript实现延时显示提示框效果
Jun 01 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
Jul 03 Javascript
JavaScript中正则表达式使数字、中文或指定字符高亮显示
Oct 31 Javascript
JS实现点击复选框变更DIV显示状态的示例代码
Dec 18 Javascript
vue基本使用--refs获取组件或元素的实例
Nov 07 Javascript
深入浅析vue全局环境变量和模式
Apr 28 Javascript
mustache.js实现首页元件动态渲染的示例代码
Dec 28 Javascript
ES6 解构赋值的原理及运用
May 25 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
利用PHP制作简单的内容采集器的代码
2007/11/28 PHP
php常用的安全过滤函数集锦
2014/10/09 PHP
YII2框架中excel表格导出的方法详解
2017/07/21 PHP
让iframe自适应高度(支持XHTML,支持FF)
2007/07/24 Javascript
一个选择最快的服务器转向代码
2009/04/27 Javascript
JavaScript 闭包深入理解(closure)
2009/05/27 Javascript
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(上:事件篇)
2010/03/24 Javascript
使用JS+plupload直接批量上传图片到又拍云
2014/12/01 Javascript
node.js中的fs.lchmod方法使用说明
2014/12/16 Javascript
JavaScript操作DOM元素的childNodes和children区别
2015/04/01 Javascript
JavaScript获取页面中表单(form)数量的方法
2015/04/03 Javascript
jQuery操作iframe中js函数的方法小结
2016/07/06 Javascript
JavaScript实现多栏目切换效果
2016/12/12 Javascript
js-FCC算法-No repeats please字符串的全排列(详解)
2017/05/02 Javascript
underscore之Chaining_动力节点Java学院整理
2017/07/10 Javascript
ionic2中使用自动生成器的方法
2018/03/04 Javascript
p5.js入门教程之小球动画示例代码
2018/03/15 Javascript
JS中双击和单击事件冲突的解决方法
2018/04/09 Javascript
Vue使用lodop实现打印小结
2019/07/06 Javascript
layui实现鼠标移动到单元格上显示数据的方法
2019/09/11 Javascript
[03:09]2014DOTA2国际邀请赛 Mushi前队友送上祝福
2014/07/12 DOTA
python网络编程学习笔记(九):数据库客户端 DB-API
2014/06/09 Python
Python中用post、get方式提交数据的方法示例
2017/09/22 Python
将python安装信息加入注册表的示例
2019/11/20 Python
PyQt5如何将.ui文件转换为.py文件的实例代码
2020/05/26 Python
python中常见错误及解决方法
2020/06/21 Python
python中如何使用虚拟环境
2020/10/14 Python
美国电子元器件分销商:Newark element14
2018/01/13 全球购物
写一个方法1000的阶乘
2012/11/21 面试题
大学生毕业自我鉴定范文
2013/09/19 职场文书
大宝sod蜜广告词
2014/03/21 职场文书
个人借款担保书
2014/04/02 职场文书
中学生英语演讲稿
2014/04/26 职场文书
生产工厂门卫岗位职责
2014/09/26 职场文书
python实现简易自习室座位预约系统
2021/06/30 Python
win10频率超出范围怎么办?win10老显示超出工作频率范围的解决方法
2022/07/07 数码科技