浅谈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 相关文章推荐
javascript针对DOM的应用分析(二)
Apr 15 Javascript
Function.prototype.bind用法示例
Sep 16 Javascript
Jquery获取元素的父容器对象示例代码
Feb 10 Javascript
基于JavaScript实现动态添加删除表格的行
Feb 01 Javascript
jQuery DataTables插件自定义Ajax分页实例解析
Apr 28 Javascript
jQuery控制li上下循环滚动插件用法实例(附demo源码下载)
May 28 Javascript
必备的JS调试技巧汇总
Jul 20 Javascript
学习vue.js表单控件绑定操作
Dec 05 Javascript
基于bootstrap的文件上传控件bootstrap fileinput
Dec 23 Javascript
浅谈angular4 ng-content 中隐藏的内容
Aug 18 Javascript
highcharts 在angular中的使用示例代码
Sep 20 Javascript
Vue使用mixins实现压缩图片代码
Mar 14 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函数(ignore_user_abort)
2012/08/01 PHP
apache中为php 设置虚拟目录
2014/12/17 PHP
Thinkphp自定义代码生成工具及用法说明(附下载地址)
2016/05/27 PHP
Ajax实现对静态页面的文章访问统计功能示例
2016/10/10 PHP
php文件上传原理与实现方法详解
2019/12/20 PHP
Json字符串转换为JS对象的高效方法实例
2013/05/01 Javascript
js控制web打印(局部打印)方法整理
2013/05/29 Javascript
分享33个jQuery与CSS3实现的绚丽鼠标悬停效果
2014/12/15 Javascript
JavaScript阻止浏览器返回按钮的方法
2015/03/18 Javascript
Jquery uploadify上传插件使用详解
2016/01/13 Javascript
jQuery实现点击后高亮背景固定显示的菜单效果【附demo源码下载】
2016/09/21 Javascript
浅谈js停止事件冒泡 阻止浏览器的默认行为(阻止超连接 #)
2017/02/08 Javascript
xmlplus组件设计系列之下拉刷新(PullRefresh)(6)
2017/05/03 Javascript
jackson解析json字符串,首字母大写会自动转为小写的方法
2017/12/22 Javascript
浅谈Vue下使用百度地图的简易方法
2018/03/23 Javascript
微信小程序实现页面跳转传递参数(实体,对象)
2019/08/12 Javascript
微信小程序顶部导航栏可滑动并选中放大
2019/12/05 Javascript
JS实现进度条动态加载特效
2020/03/25 Javascript
vue总线机制(bus)知识点详解
2020/05/10 Javascript
解决vue字符串换行问题(绝对管用)
2020/08/06 Javascript
[01:08:17]2018DOTA2亚洲邀请赛3月29日 小组赛B组 EG VS VGJ.T
2018/03/30 DOTA
python操作xml文件详细介绍
2014/06/09 Python
python 2.7.13 安装配置方法图文教程
2018/09/18 Python
python学生信息管理系统(初级版)
2018/10/17 Python
使用 Python ssh 远程登陆服务器的最佳方案
2020/03/06 Python
python用什么编辑器进行项目开发
2020/06/17 Python
html5关于外链嵌入页面通信问题(postMessage解决跨域通信)
2020/07/20 HTML / CSS
彪马美国官网:PUMA美国
2017/03/09 全球购物
德国Discount-Apotheke中文官网:DC德式康线上药房
2020/02/18 全球购物
C语言笔试集
2012/07/24 面试题
体育专业个人求职信范文
2013/12/27 职场文书
单位人事专员介绍信
2014/01/11 职场文书
工人先锋号事迹材料(2016精选版)
2016/03/01 职场文书
如何利用JavaScript实现二叉搜索树
2021/04/02 Javascript
Mysql Online DDL的使用详解
2021/05/20 MySQL
javascript之Object.assign()的痛点分析
2022/03/03 Javascript