浅谈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 相关文章推荐
向fckeditor编辑器插入指定代码的方法
May 25 Javascript
捕获键盘事件(且兼容各浏览器)
Jul 03 Javascript
使用javascript获取页面名称
Dec 23 Javascript
AspNet中使用JQuery上传插件Uploadify详解
May 20 Javascript
BootStrap 动态添加验证项和取消验证项的实现方法
Sep 28 Javascript
深入理解node.js之path模块
May 03 Javascript
webpack 1.x升级过程中的踩坑总结大全
Aug 09 Javascript
详解angular笔记路由之angular-router
Sep 12 Javascript
详解node+express+ejs+bootstrap构建项目
Sep 27 Javascript
Vue中使用vee-validate表单验证的方法
May 09 Javascript
Node.js中的cluster模块深入解读
Jun 11 Javascript
nginx配置域名后的二级目录访问不同项目的配置操作
Nov 06 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
资料注册后发信小技巧
2006/10/09 PHP
laravel框架语言包拓展实现方法分析
2019/11/22 PHP
用于table内容排序
2006/07/21 Javascript
js中的window.open返回object的错误的解决方法
2009/08/15 Javascript
javascript开发技术大全 第4章 直接量与字符集
2011/07/03 Javascript
基于jquery实现的移入页面上空文本框时,让它变为焦点,移出清除焦点
2011/07/26 Javascript
jQuery把表单元素变为json对象
2013/11/06 Javascript
使用js解决由border属性引起的div宽度问题
2013/11/26 Javascript
JS、CSS加载中的小问题探讨
2013/11/26 Javascript
一个获取第n个元素节点的js函数
2014/09/02 Javascript
初识Node.js
2014/09/03 Javascript
director.js实现前端路由使用实例
2015/02/03 Javascript
JavaScript必知必会(九)function 说起 闭包问题
2016/06/08 Javascript
jQuery之简单的表单验证实例
2016/07/07 Javascript
Javascript中关于Array.filter()的妙用详解
2016/12/04 Javascript
微信小程序小组件 基于Canvas实现直播点赞气泡效果
2020/05/29 Javascript
Windows安装Node.js报错:2503、2502的解决方法
2017/10/25 Javascript
vue-cli项目代理proxyTable配置exclude的方法
2018/09/20 Javascript
创建echart多个联动的示例代码
2018/11/23 Javascript
100行代码实现vue表单校验功能(小白自编)
2019/11/19 Javascript
Vue中fragment.js使用方法小结
2020/02/17 Javascript
JS倒计时两种实现方式代码实例
2020/07/27 Javascript
[52:15]2014 DOTA2国际邀请赛中国区预选赛5.21 HGT VS LGD-GAMING
2014/05/23 DOTA
Python中的测试模块unittest和doctest的使用教程
2015/04/14 Python
python脚本内运行linux命令的方法
2015/07/02 Python
pandas实现DataFrame显示最大行列,不省略显示实例
2019/12/26 Python
关于tensorflow的几种参数初始化方法小结
2020/01/04 Python
Python Numpy,mask图像的生成详解
2020/02/19 Python
为什么相对PHP黑python的更少
2020/06/21 Python
推广活动策划方案
2014/08/23 职场文书
家庭教育的心得体会
2014/09/01 职场文书
中国文明网向国旗敬礼活动精彩寄语2014
2014/09/27 职场文书
党的群众路线教育实践活动查摆问题自查报告
2014/10/10 职场文书
运动会开幕式致辞
2015/07/29 职场文书
企业内部管理控制:采购授权审批制度范本
2020/01/19 职场文书
深入解析MySQL索引数据结构
2021/10/16 MySQL