基于vue的web前端性能优化

1. 问题引入

使用vue开发项目,部署后发现web端性能较差,存在内存大量占用。特分析此项目,优化基于vue的web端性能,以提升用户体验。

2. 问题分析

2.1 通过查看部署的平台,发现以下几大现象

1、  首次进入平台,加载缓慢,大概5s空白页;

2、  切换模块时,单个模块加载缓慢;

3、  模块切换多次后,内存大量占用,导致页面卡顿或无响应(ie下);

 基于vue的web前端性能优化_第1张图片

图1 首次加载

基于vue的web前端性能优化_第2张图片

图2 多次切换

 

4、  调用OCX控件的页面在多次切换后,内存无法释放,比其他模块响应时间更长;

5、  通过抓包发现,菜单切换多次后,单个接口请求数量会累加;

6、  通过查看代码,发现有不必要的jq引入,并进行不必要的dom操作;

7、  通过查看代码,发现echarts并未按需引入;

8、  单个vue文件过大,并未做组件提取、页面拆分和公共方法提取,大量冗余代码;

2.2 问题分析

1、  首屏加载慢

打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

2、  切换模块时,单模块加载缓慢

l  单个模块在初始化时调用大量接口,如:需要tab切换才显示的树、列表等均在首次加载时调用接口,http连接数并发过多,导致加载缓慢。

l  单个模块大量接口返回有效数据极少,如平台名称、端口号等均由不同的接口返回,暂用了http连接,若是合并这部分接口,也可提高响应速度。

3、  模块切换多次后,内存大量占用

打包构建应用时,未对路由懒加载,所有模块均打包在一个文件中,Javascript 包会变得非常大,影响页面加载。

4、  调用OCX控件的页面在多次切换后,内存无法释放

Vue-router中切换单入口模块,由于并未真正切换页面,调用的OCX控件在每次的实例化中均占用内存,导致内存未释放。若是可以在OCX控件模块单独配置入口,切换过程中可自动释放内存。

5、  菜单切换多次后,单个接口请求数量会累加

组件之间传递数据方式错误,且在数据挂载的时候生成实例,导致事件被重复绑定触发,产生大量并发请求。各浏览器对并发的http连接数量有限制,超过数量在ie下http连接会挂起,chrome下也会导致响应缓慢、卡顿。

6、  不必要的jq引入和不必要的dom操作

通过查看代码,发现项目中引入了jq,仅用于菜单切换时,操作菜单DOM,进行addClass和removeClass操作。在基于vue的项目中需要实现这样的效果,可直接通过数据驱动,添加三元运算即可。Jq的引入和dom操作没有必要。

7、  echarts并未按需引入

项目中仅使用地图(map)、柱状图(bar)和折线图(line),在生产环境引入完整echarts会增加该http请求体积,若是按需引入需要使用的组件,可优化该http连接,减少响应时间。

8、  单个vue文件过大,并未做组件提取、页面拆分和公共方法提取,大量冗余代码

通过代码走查,发现项目中未做共用组件规划、提取。如:tab切换搜索条件,仅改变搜索条件中的一个类型,却在项目中重复初始化其中的下拉树等。单个vue文件可达四千行,大量冗余代码,维护异常困难。

3. 问题总结

通过问题分析,主要有以下方向需要优化:

1、  Vue-router优化

2、  http连接优化

3、  vue- components优化

4、  代码优化

5、  打包优化

4. 如何优化

4.1 Vue-router优化

4.1.1 路由懒加载

当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载,也可将组件按组分块。

  • 使用const Foo = () => import('./Foo.vue')代替import './Foo.vue';
  • 详见vue-router官网——路由懒加载https://router.vuejs.org/zh-cn/advanced/lazy-loading.html;

4.2 http连接优化

HTTP协议定义Web客户端如何从服务器请求web页面,以及服务器如何把web页面传送给客户端,浏览器请求获取数据通过http连接完成,因此,优化http连接优化是web项目优化的重要方向之一。Web项目的由浏览器呈现,下面我们来看看浏览器对请求的处理过程,如图3:

 基于vue的web前端性能优化_第3张图片

图3 浏览器请求处理流程图

 

4.2.1 减少HTTP请求

  • 合并CSS、js、图片。将css、js、图片合并,可以有效减少http请求数;
  • 合理规划API,将可合并的接口请求合并。浏览器对并发的http请求数量有限制,即使API响应很快,在多个接口并发请求时,仍会在浏览器中造成不同程度的卡顿(如ie中部分请求挂起,内存占用变大等);

4.2.2 合理使用缓存

合理设置HTTP缓存。从图1 浏览器请求处理流程图中可以看出,恰当的缓存设置可以大大减少HTTP请求,节省带宽。如很少变化的资源(html、css、js、图片等)通过 HTTP Header中的cache-control和Expires可设定浏览器缓存,变化不频繁又可能变的资源使用Last-Modifed来做请求验证。

4.2.3 使用字体图标

建议使用字体图标代替纯色或渐变色的图标,如使用icomoon。在准备好svg文件后,可通过https://icomoon.io/在线制作字体图标,需要维护时可导入json文件重新编辑。

使用字体图标的优点:

  • 轻量:一个图标字体比一系列的图像(特别是在Retina屏中使用双倍图像)要小。一旦图标字体加载了,图标就会马上渲染出来,不需要下载一个图像。可以减少HTTP请求,还可以配合HTML5离线存储做性能优化;
  • 灵活性:图标字体可以用过font-size属性设置其任何大小,还可以加各种文字效果,包括颜色、Hover状态、透明度、阴影和翻转等效果。可以在任何背景下显示。使用位图的话,必须得为每个不同大小和不同效果的图像输出一个不同文件。
  • 兼容性:网页字体支持所有现代浏览器,包括IE低版本。

4.2.4 图片懒加载

在实际的项目开发中,我们通常会遇见这样的场景:一个页面有很多图片,而首屏出现的图片大概就一两张,那么我们还要一次性把所有图片都加载出来吗?显然这是愚蠢的,不仅影响页面渲染速度,还浪费带宽。这也就是们通常所说的首屏加载,技术上现实其中要用的技术就是图片懒加载--到可视区域再加载。

4.3 组件优化

现大部分业务或管理系统中,模块较多、单模块功能较多的情况时有发生,若是组件没有划分好,会导致页面加载缓慢,影响用户体验和使用。针对此情况,可将模块内按照布局或功能重新划分vue组件:

  • 按模块划分路由。按照业务模块划分路由及子路由,保证模块间的隔离;
  • 模块内按布局或功能划分组件。单个模块功能较多或逻辑较复杂时,按照布局划分为左右或上下及其组合模式划分组件,以子组件的方式放在模块中,方便打包优化、复用、功能拓展及维护;
  • 能复用的组件尽量复用。布局、功能模块等均可复用,如:tab中的筛选条件、详情弹窗、表单等。

4.4 代码优化

4.4.1 第三方引入优化

  • 去除不必要的引入,如jq;
  • 按需引入echarts包;

4.4.2 基础优化

  • Vue官网中的规范需要遵循,在此不再赘述https://cn.vuejs.org/v2/guide/;
  • v-if,v-show的选择。权限相关使用v-if、频繁切换使用v-show、不频繁切换使用v-if;
  • style中使用