详解Vue SPA项目优化小记


Posted in Javascript onJuly 03, 2018

概述

之前做了一个React项目和Vue的项目,在做完后不加任何优化的情况下,这2个项目的首屏加载平均时间居然达到了20+s,好一点能进10s,差一点快30s,完全不能忍,优化势在必行,本文章记录下Vue项目的优化过程,React项目的优化后续补上。

详解Vue SPA项目优化小记

上图是Vue项目的首页,整个项目由vue-cli搭建,主要分为4个模块,见页面左侧导航栏,总体代码量不算太大,组件的话总共50个左右吧,项目结构见下图,不算特别大的项目,但是首屏加载时间居然这么慢。

详解Vue SPA项目优化小记

首先得确定到底是哪里导致了首屏渲染如此之慢?打开Chrome Network面板,勾上Disable cache选项,刷新页面观察资源加载情况,发现罪魁祸首就是webpack打包生成的app.js和vendor.js,其中vendor.js大小达到了1.2M,下载时间超过20秒,app.js也快到1M,而manifest.js不是很大。vendor.js主要是把node_modules里所用到的modules都合并成一个js了,所以比较大.而我们也希望将业务代码和第三方引用分开打包。 manifest.js 包含webpack的runtime代码和module manifest代码,作用是防止修改了代码但是没有修改第三方库文件导致第三方库文件也打包的问题。

网上一番搜索,发现优化点主要在如下几个方面:

  1. 开启gzip压缩功能
  2. 引入CDN
  3. 路由懒加载
  4. 某些第三方组件按需加载而不是全部加载
  5. 较小的图片资源用base64嵌入src中,减少http请求

具体优化

gzip压缩

gzip是GNUzip的缩写,最早用于UNIX系统的文件压缩。HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器)必须共同支持gzip。目前主流的浏览器,Chrome,firefox,IE等都支持该协议。常见的服务器如Apache,Nginx,IIS同样支持,gzip压缩效率非常高,通常可以达到70%的压缩率,也就是说,如果你的网页有30K,压缩之后就变成了9K左右

我后端是用的express,开启gzip非常简单,首先npm install compression安装中间件,然后在app.js里添加use使用即可:

var compression = require('compression');
var app = express();
app.use(compression())

重启服务,观察网络面板里面的response header,如果看到如下红圈里的字段则表明gzip开启成功

详解Vue SPA项目优化小记

引入CDN

CDN(内容分发网络),是一种公共服务,他本身有很多台位于不同地域、接入不同运营商的服务器,而所谓的使用CDN实质上就是让CDN作为网站的门面,用户访问到的是CDN服务器,而不是直接访问到网站。由于CDN内部对TCP的优化、对静态资源的缓存、预取,加上用户访问CDN时,会被智能地分配到 最近 的节点,降低大量延迟,让访问速度可以得到很大提升

一个原则是尽量将比较大的第三方库放到cdn上去以减少请求时间,在我的项目中,我将vue,vuex,vue-router,echarts都放到了cdn上,具体操作是打开BootCDN 然后搜索关键字并copy链接粘贴到index.html的body闭合标签前,如下图

详解Vue SPA项目优化小记

注意选取min.js(体积最小),然后在webpack.base.conf.js里设置externals选项,目的是不打包这些选项,由于index.html中script的引入,比如vue就会有一个全局变量Vue存在,因此这里external的value就是Vue

externals: {
 'vue': 'Vue',
 'vuex': 'Vuex',
 'vue-router': 'VueRouter',
 'echarts': 'echarts'
 },

cdn使用后优势是巨大的,观察network面板,时间几乎都在50ms以下

详解Vue SPA项目优化小记

路由懒加载

路由懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。像vue这种单页面应用,如果没有应用懒加载,运用webpack打包后的文件将会异常的大,造成进入首页时,需要加载的内容过多,时间过长,会出现长时间的白屏,即使做了loading也是不利于用户体验,而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效的分担首页所承担的加载压力,减少首页加载用时。

Vue官网的示例如下,采用异步组件和webpack的code-splitting结合

详解Vue SPA项目优化小记

因此在项目中,进入router的index.js中,将原来的 import Comp from '@/component/xxx' 改为如下,vue-router的配置项还是保持不变

//异步组件,路由懒加载
const BookMark = resolve => require(['@/components/BookMark'],resolve);
const HotBookMark = resolve => require(['@/components/HotBookMark'],resolve);
const ImportBookMark = resolve => require(['@/components/ImportBookMark'],resolve);
const Default = resolve => require(['@/components/Default'],resolve);

打包后查看js文件夹下的文件,会多出上述文件,每个进行懒加载的组件都会生成一个js,如下图红框内

详解Vue SPA项目优化小记

第三方按需加载

比如本项目里面使用的echarts,只用到了一个柱状图组件,其余的都没有用到,但是这样import后打包时却会把整个echarts都打入包内,造成空间浪费

import echarts from 'echarts'

因此只需要import用到的组件即可,如下,这样就可以减少很多不必要的体积

import echarts from 'echarts/lib/echars'
import 'echarts/lib/chart/bar'
import 'echarts/lib/component/legend'
import 'echarts/lib/component/title'

图片转base64

小图片可以转为base64字符串然后嵌入img的src中,节省http请求数量,webpack中用url-loader处理,limit控制了图片转base64的阈值,小于该值就转base64

{
 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
 loader: 'url-loader',
 options: {
  limit: 10000,
  name: utils.assetsPath('img/[name].[hash:7].[ext]')
 }
 },

优化后性能

经过上述优化后,首页打开时间迅速下降,DomContentLoaded用时不到1s,load完全加载用时不到4s,耗时较多的是几张背景大图,本来体积就大,后续考虑放到cdn上

详解Vue SPA项目优化小记

这是最初的优化策略,后续继续会进行深度优化。

ps:webpack-bundle-analyzer是神器,能够有效分析出包占用的体积情况~下图是最终优化后的包组成结构图,最初打包的结构图比下图大很多,主要多了echarts,vue,vue-router,vuex模块

详解Vue SPA项目优化小记

优化后的整个包gzip后大小喜人~

详解Vue SPA项目优化小记

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

Javascript 相关文章推荐
游览器中javascript的执行过程(图文)
May 20 Javascript
JavaScript中json对象和string对象之间相互转化
Dec 26 Javascript
Jquery中使用setInterval和setTimeout的方法
Apr 08 Javascript
javascript实现切换td中的值
Dec 05 Javascript
JavaScript数组去重由慢到快由繁到简(优化篇)
Aug 26 Javascript
使用微信小程序开发前端【快速入门】
Dec 05 Javascript
JavaScript中localStorage对象存储方式实例分析
Jan 12 Javascript
JQuery.dataTables表格插件添加跳转到指定页
Jun 09 jQuery
web前端开发中常见的多列布局解决方案整理(一定要看)
Oct 15 Javascript
vue改变对象或数组时的刷新机制的方法总结
Apr 24 Javascript
Vue SPA 初次进入加载动画实现代码
Nov 14 Javascript
详解ES6 CLASS在微信小程序中的应用实例
Apr 24 Javascript
jQuery实现表单动态添加与删除数据操作示例
Jul 03 #jQuery
JS实现显示当前日期的实例代码
Jul 03 #Javascript
jQuery实现获取form表单内容及绑定数据到form表单操作分析
Jul 03 #jQuery
vue 设置路由的登录权限的方法
Jul 03 #Javascript
jQuery阻止事件冒泡实例分析
Jul 03 #jQuery
详解VUE中常用的几种import(模块、文件)引入方式
Jul 03 #Javascript
Vue props用法详解(小结)
Jul 03 #Javascript
You might like
PHP 存储文本换行实现方法
2010/01/05 PHP
PHP+jQuery 注册模块的改进(一):验证码存入SESSION
2014/10/14 PHP
php基于jquery的ajax技术传递json数据简单实例
2016/04/15 PHP
Bootstrap+PHP实现多图上传功能实例详解
2018/04/08 PHP
JavaScript 学习笔记二 字符串拼接
2010/03/28 Javascript
asp.net+js 实现无刷新上传解析csv文件的代码
2010/05/17 Javascript
文件编码导致jquery失效的解决方法
2013/06/26 Javascript
使用jquery获取网页中图片高度的两种方法
2013/09/26 Javascript
基于javascript实现根据身份证号码识别性别和年龄
2016/01/22 Javascript
JavaScript实现给定时间相加天数的方法
2016/01/25 Javascript
关于Bootstrap弹出框无法调用问题的解决办法
2016/03/10 Javascript
jquery $.trim()去除字符串空格的实现方法【附图例】
2016/03/30 Javascript
基于javascript实现最简单的选项卡切换效果
2016/05/16 Javascript
使用vue实现点击按钮滑出面板的实现代码
2017/01/10 Javascript
JS设计模式之数据访问对象模式的实例讲解
2017/09/30 Javascript
vue.js表单验证插件(vee-validate)的使用教程详解
2019/05/23 Javascript
Emberjs 通过 axios 下载文件的方法
2019/09/03 Javascript
JS document对象简单用法完整示例
2020/01/14 Javascript
详解vuejs中执行npm run dev出现页面cannot GET/问题
2020/04/26 Javascript
Vue组件为什么data必须是一个函数
2020/06/11 Javascript
[00:33]2016完美“圣”典风云人物:BurNIng宣传片
2016/12/10 DOTA
Python 探针的实现原理
2016/04/23 Python
itchat接口使用示例
2017/10/23 Python
服务器端jupyter notebook映射到本地浏览器的操作
2020/04/14 Python
Python常用GUI框架原理解析汇总
2020/12/07 Python
一款利用css3的鼠标经过动画显示详情特效的实例教程
2014/12/29 HTML / CSS
使用html2canvas将页面转成图并使用用canvas2image下载
2019/04/04 HTML / CSS
基于Html5实现的语音搜索功能
2019/05/13 HTML / CSS
2014年元旦活动方案
2014/02/15 职场文书
2014领导班子四风剖析对照检查材料思想汇报
2014/09/20 职场文书
一年级语文下册复习计划
2015/01/17 职场文书
英语教师个人总结
2015/02/09 职场文书
2015年房地产个人工作总结
2015/05/26 职场文书
学习《中小学教师职业道德规范》心得体会
2016/01/18 职场文书
vue项目中的支付功能实现(微信支付和支付宝支付)
2022/02/18 Vue.js
联想win10摄像头打不开怎么办?win10笔记本摄像头打不开解决办法
2022/04/08 数码科技