admin管理员组

文章数量:1659356

爱奇艺视频生产智能云平台系统在今年进行了一次重大升级,前端团队也趁此机会将底层技术架构从三年前的 Arm.js(内部MVC框架)+ Java BFF + Velocity 模板完全切换到了 Vue.js + Node.js BFF 的技术栈。

新的前端应是一个拥有超过十个业务模块的单页面应用,每个模块已经通过路由懒加载进行了拆分,同时公共的第三方依赖也拆分到了单独的 Vendor 文件。不过在上线试用初期,用户还是普遍反馈页面打开速度较老版本有比较明显的下降,存在几秒钟不等的白屏等待时间。

为了提升用户体验和使用效率,团队内部对新版前端应用进行了多次优化,最终效果提升非常显著。本文的主要内容就是针对中后台 Web 应用性能的分析思路解决方案的总结分享。

问题梳理

我们先通过提问题的方式,从资源文件加载、页面渲染性能、接口响应速度等三个方面分别列出了一些可能存在性能瓶颈的环节。

资源加载问题

在一个复杂的 Web 应用中,通常会依赖很多 JS/CSS/Images 等资源文件。如何在最短时间内获取页面所需的最小资源,我们需要考虑以下几个问题:

  • 源码中有无冗余的模块?是否进行了压缩、合并等操作?

  • 服务器响应及网络传输速度是否正常?有没有最大化利用浏览器的并发请求?

  • 资源文件的缓存策略是否合理?是否每次发布上线都需要重新请求所有文件?

  • 首次页面渲染是否下载了不必要的资源文件?每次渲染所需的资源文件能不能提前加载?

页面渲染问题

由于 JS 是在单线程中执行,而 Vue.js 框架的大部分渲染任务都在浏览器端完成。为了解决白屏、卡顿等问题,我们需要考虑以下几个问题:

  • 是否可以通过骨架屏等方式提前渲染核心布局?

  • 主线程是否存在非常耗时的长任务?是否可以进行任务分片、延迟渲染?

  • 是否存在时间复杂度过高的算法?是否存在大量重复计算?

  • 是否重复初始化相同的对象?是否存在内存泄露?

接口速度问题

在列表查询等依赖后台数据展示的页面,接口的响应速度也至关重要。由于我们通过 Node.js 搭建的 BFF 来整合多个服务提供方的接口,因此可能存在以下几个问题:

  • 后端服务提供的接口速度是否响应慢?网关、数据库、索引等服务是否正常?

  • 针对实时性要求较低的数据,是否可以利用缓存服务?

  • 同时调用多方接口时,是否最大化进行并发请求?非必要接口是否可以单独发起请求?

  • 与浏览器脚本一样,是否存在复杂算法、内存泄露等问题代码?

解决方案

带着以上的这些问题,我们开始着手对现有的应用进行一次详细的检查,逐步定位影响性能的关键问题并一一进行解决。

资源加载优化

Webpack 构建问题分析

由于我们的项目通过 Webpack 4.x 构建,因此为了分析资源文件的个数及大小,采用了 Webpack 插件webpack-bundle-analyzer对产出的静态资源文件进行了统计,如下图所示(截取了几个体积较大的文件)。

根据统计我们发现了以下几个主要问题:

  • 缓存问题。每次改动任意代码,所有生成的 JS/CSS 等文件的 Hash 值都发生了变化,这意味着每次发布上线,浏览器都需要重新请求全部资源。

  • 文件大小。通过 node_modules 生成的 chunk-vendor 原始大小超过 1.5 M。其中,体积最大的是 ElementUI,超过 650K,其次是 moment.js,体积超过 250K。剩余部分则由 Vue.js、Lodash 等基础类库组成。

  • 重复打包。部分业务模块对应的 chunk 文件原始大小在 500K 左右。其原因是使用到了 d3,echarts 等依赖的模块,直接将它们打包到了对应模块中。而这些第三方库,占整个文件大小的 70% 左右。

  • 资源个数。由 Webpack 自动生成了多个模块间的公共 chunk,大

本文标签: 后台性能爱奇艺中web