作者: vivo 互联网大数据团队- Wang Lei

本文是vivo互联网大数据团队《BI 数据可视化平台建设》系列文章第3篇。

随着越来越多代码的堆积,平台的运行加载性能也在逐步下降,在不同程度上极大地影响了用户体验,从而导致用户流失。本文就是从这样的一个背景出发,通过对BI数据可视化平台的一系列的性能优化实践,给大家系统性阐述首页性能优化的核心策略,并探讨在日常开发中如何实现长效性能保障。

往期系列文章:

  1. BI 数据可视化平台建设(1)—交叉表组件演变实战

  2. BI 数据可视化平台建设(2)—筛选器组件升级实践

文章太长?1分钟看图抓住核心观点

一、背景

随着业务的拓展和用户数量的激增,平台经历了多个周期的快速迭代,整体功能场景也越发复杂的。在快速迭代的过程中,我们很容易忽略平台的性能,到了某一个节点,猛地发现,随着越来越多代码的堆积,平台的运行加载性能也在逐步下降,在不同程度上极大地影响了用户体验,从而导致用户流失。本文就是从这样的一个背景出发,通过对BI数据可视化平台的一系列的性能优化实践,给大家分享一下如何提升首页性能的思路,并且让我们在日常开发中,如何持续保持高性能,而不是又一次回过头来优化性能。本文主要给大家介绍一平台在进行首页性能提升的一些实践经验。

二、了解性能指标

2.1  用户体验核心指标

衡量一个 Web 页面的体验和质量有非常多的指标,根据页面加载流程可以将指标分成三大类:

  • 文档加载相关(TTFB、DCL等)

  • 内容呈现相关(LCP、FCP、FMP 等)

  • 交互响应相关(INP、FPS 等)

针对这么多的性能指标,Google 提出了网站用户体验的三大核心指标 (LCP INP CLS),分别用来衡量用户感知的加载速度、量化网页首次互交互的感受、衡量网页视觉的稳定性:

图片来源:https://web.dev/

2.2  平台度量指标

但是在实际规划平台性能度量体系时,我们可以根据自身的业务和需求进行自定义,针对数据可视化平台来说,我们更看重用户感知的加载速度,如何让用户快速看到数据可视化内容是我们首页性能优化的关键,因此我们性能指标主要以文档加载和内容呈现为主,这里我们以 TTFB、FCP、LCP  作为我们首页性能的度量指标,它们涵盖了网络请求到页面主要内容加载的过程:

网络请求过程(网络响应衡量指标 TTFB):

TTFB 主要指的是以下请求阶段耗时的总和:

  • 重定向时间

  • Service Worker 启动时间(如果有)

  • DNS 查找

  • 连接和 TLS 协商

  • 请求,直到响应的第一个字节到达

页面主要内容加载过程(内容呈现衡量指标 FCP、LCP):

图片来源:https://web.dev/

  • TTFB(Time to First Byte ):

它主要测量的是在网络请求阶段中,从请求资源到响应的第一个字节到达所经过的时间,这有助于识别 Web 服务器因速度过慢而无法响应请求。由于 TTFB 发生在指标 FCP(First Contentful Paint ) 和 LCP(Largest Contentful Paint)之前,因此希望服务器能够快速地响应导航请求。一般来说,大多数网站都应尽量将 TTFB 控制在 0.8秒 以内,且超过75%以上PV 达到该范围。

图片来源:https://web.dev/

  • FCP(First Contentful Paint):

它用于标记网页加载过程中用户可以在屏幕上看到的第一个元素所用的时间。元素主要是指文本、图片(包括背景图片)、SVG 或 Canvas。可以用于衡量用户感知的加载速度。为了提供良好的用户体验,网站的 FCP 最好不要超过 1.8 秒,且确保超过75%以上PV 达到该范围。

图片来源:https://web.dev/

  • LCP(Largest Contentful Paint):

它用于标记网页加载过程中加载了网页主要内容的时间点。可以用于衡量用户感知的加载速度,也是Google 提出的度量用户体验的三大核心指标之一。为了提供良好的用户体验,网站的 LCP 最好控制在 2.5 秒 以内,且确保超过75%以上PV 达到该范围。

图片来源:https://web.dev/

三、首页性能现状

背景:性能问题主要是由于前期开发人力有限、功能快速迭代等原因,导致代码质量和可维护性较差,积累下的技术债务。

(1)平台性能指标分析:LCP(首屏平均耗时) 高达3.3s,远高于Google  LCP衡量的标准(2.5s)。

(2)通过Lighthouse工具进行性能分析,性能得分较低,各项性能指标都处于不及格的水平。

四、分析性能问题

4.1 通过Network面板分析

从Network面板上,可以分析得出加载过程中存在以下几类问题:

  • 入口文件体积太大,加载耗时长,阻塞其他资源加载

  • 低优先级资源阻塞了高优先级资源加载

  • 微前端子应用等非首屏依赖资源没有进行异步加载

  • 网络传输协议还处于HTTP1.1,传输效率低

  • 接口请求传输的数据体过大,存在大量冗余数据

4.2 通过Performance面板分析

从 Performance 面板上,可以分析得出加载过程中存在以下几类问题:

  • FPS 长时间出现红色条形,表示帧速率下降得太低,可能出现动画延迟卡顿等问题

  • CPU 资源占用率过高,可能出现性能问题

  • 主线程存在多个 Long Task(长任务),阻塞了页面加载渲染

4.3 通过Lighthouse工具分析

通过 Lighthouse 工具,可以分析得出加载过程中存在以下的问题:

  • 大量 Long Task 阻塞了主线程工作

  • 存在阻塞渲染的低优先级资源

  • DOM节点数过多,增加了内存占用,样式计算用时延长,并产生高昂的布局重排成本

  • 图片资源不是最优压缩效果的格式

  • 存在大量未使用的CSS和JS文件代码

五、优化实践

5.1 优化方向 (时间和空间)

通过上述的问题分析,我们可以分析出资源加载渲染耗时以及浏览器性能资源占有 都有可能导致页面卡顿缓慢,影响用户体验,因此可以从耗时和资源占用两方面来进行性能优化,也可以理解成时间和空间的优化。

5.2 时间优化 (网络耗时、加载耗时、渲染耗时等)

(1)网络传输耗时优化

网络传输耗时优化主要可以从 缓存策略、传输协议、资源预加载预解析、CDN 等几个方向进行。本次优化主要是通过网络传输升级、资源预加载、请求性能优化等方面来讲解一下。

  • 网络传输协议升级,由 HTTP/1.1 升级至 HTTP/2.0 版本,通过 HTTP/2.0 多路复用的特性解决了请求并发数限制的问题,同时二进制传输和头部压缩等特性也提高了网络传输的效率。

  • 删除资源预加载(Preload),减少首页非关键资源的预加载处理。通过加载瀑布流可以看到,这里提前加载了多个非首屏关键资源的字体文件,且文件体积高达 1.8MB,阻塞了首屏关键资源的加载解析。所以我们需要根据资源的优先级,合理的使用 Preload(预加载)和 Prefetch(预解析)。

  • 请求性能优化,降低请求响应耗时。通过Network面板可以看到,首页依赖的主要接口返回的数据体在没压缩前高达 3.1 MB,这里我们对请求内容进行了分析,通过异步请求、减少非关键的冗余数据等处理将传输数据体积降低到了 500KB 内。除了减少数据传输量,我们还可以通过请求合并,利用缓存等减少通信次数来进行请求性能优化。

(2)资源加载耗时优化

资源加载耗时优化可以从 代码压缩、代码分包、组件、工具库、ICON等按需加载等几个方向进行。主要是通过优化体积来减少资源加载耗时,从而提升首屏性能。

  • 首先通过 webpack-bundle-analyzer 插件对包体积进行分析,可以看到 chunk-vendors.js 文件体积较大,同时还存在依赖嵌套等问题,导致资源加载缓慢。本次优化我们通过代码分包、资源按需加载,图片格式优化等措施,减少了资源体积, chunk-vendors.js 文件也从 2.3MB 降低到 480KB。下面我们通过几个具体示例进行讲解:

    对 Echarts 、Ant-Design-Vue-1.x ICON等UI工具库进行按需加载。

// 优化前 在入口文件进行全量的同步加载 
import \* as echarts from 'echarts/core'; 
import { XXXChart } from 'echarts/charts'; 
import { XXXComponent } from 'echarts/components'; 
import { CanvasRenderer } from 'echarts/renderers';  echarts.use(\[XXXChart, XXXComponent, CanvasRenderer\]); // 优化后 根据使用场景进行按需加载 
async function initEcharts(chartType){
  const echarts = await import('echarts/core');
  const { XXXChart} = await import('echarts/charts');
  const { XXXComponent } = await import('echarts/components');
  const { CanvasRenderer } = await import('echarts/renderers');
  echarts.use(\[XXXChart, XXXComponent, CanvasRenderer\]);
}

由于历史需求迭代原因,我们对 Ant-Design-Vue-1.x 进行了二次定制开发,这也导致了ICON全量引入,我们这里使用的方案是重定向到本地文件来进行控制 ,使用 alias 将 @ant-design/icons/lib/dist 指向项目中的 antdIcon.js,然后在 antdIcon.js 文件中按需导出即可,通过按需加载,ICON引入体积从 500K+ 降低到 30K+

// vue.config.js alias配置
resolve: {
  alias: {
    '@ant-design/icons/lib/dist$': path.resolve(\_\_dirname, './src/plugins/antdIcons.js'),
  }
} // src/plugins/antdIcons.js
export { default as CheckCircleOutline } from '@ant-design/icons/lib/outline/CheckCircleOutline';
export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';
  • 检查删除冗余依赖,避免重复npm包引入;随着平台长期的发展迭代,或多或少都会存在冗余的 mf、npm 资源,同时我们在对微前端子应用的包体积进行分析时,发现子应用通过 npm 引入的Echarts,而主应用本身也引入相同的库,相对于引入了2 遍 Echarts,这个时候我们改造了子应用的依赖引入方式,通过传参的方式将Echarts实例传递给子应用,避免重复引入和加载相同资源。

//主应用 通过props传递依赖
import { start, loadMicroApp, prefetchApps } from 'qiankun'; export default {
  name: 'MicroWidgetReact',
  methods: {
    async loadMicroApp(){
      const $echarts = await this.$initEcharts();
      this.microApp = loadMicroApp({
        name: \`xxx\`,
        props: {
          ...props,
          $echarts: $echarts,
        },
      });
    },
  },
}; //子应用配置 externals 并且外链依赖加上 ignore 属性(这是自定义的属性,非标准属性)
<script ignore src\="https://cdn.jsdelivr.net/npm/echarts@5.5.0/dist/echarts.min.js"\></script> // 当它独立运行时,使用自己的外链依赖 window.$echarts
const $echarts = parent.$echarts || window.$echarts;
  • 对图片、字体等资源文件进行格式优化;我们将图片资源统一转换成WEBP格式,除了文件大小和压缩效率上有优势,WEBP还支持透明度和动态图像等,所以如果不需要考虑 IE以及旧版本Safri的兼容性,WebP 格式更适用于网页开发;而字体文件则转换成WOFF2格式,对比 TTF 格式在文件大小、压缩效率和安全性上都更具优势。

5.3 空间优化 (CPU 占用、内存占用、本地缓存等)

我们在做性能优化的时候,很多情况下都会依赖时间换空间、或者空间换时间等方式,这里需要根据项目的实际情况做出取舍,选择相对合适的一种方案去进行优化。资源占用常见的优化方式包括:

  • 代码优化:精简和优化 JavaScript 和 CSS 代码,避免使用过多的循环和递归操作,减少对 CPU 的占用。

  • 避免内存泄漏:定期检查并优化内存使用,避免出现内存泄漏问题,可以使用浏览器的开发者工具进行内存分析。

  • 图片懒加载:延迟加载图片,只有当图片进入可视区域时再加载,减少内存占用。

  • 数据本地存储:使用浏览器提供的本地存储功能(如LocalStorage或IndexedDB),将一些数据缓存到本地,减少对网络请求的依赖,提高性能。

  • 使用 Web Workers:将一些耗时的任务放到 Web Workers 中执行,减轻主线程的负担,从而减少 CPU 占用。

  • 使用服务端渲染:使用服务端渲染技术,减少客户端的计算压力,提高页面加载速度。

  • 使用资源压缩:对 JavaScript、CSS、图片等资源进行压缩,减小文件大小,降低网络传输和内存占用。

本次我们主要使用了 Web Workers 和 数据解绑 (Object.freeze) 等方式进行空间优化,减少了CPU和内存的占用。通过 Web Workers 将需要复杂计算任务放到 Worker 线程,避免阻塞其他首页渲染任务,释放主线程资源,实现单线程到多线程。但是这里要注意,过多的使用 Web Workers 有时候反而会导致资源的过度占用,因为 Web Workers 本身也会占用一定的内存资源,而 Workers 之间的通信和数据同步也可能会带来复杂性和性能开销,特别是在大规模的并发任务处理时,所以我们需要根据场景合理使用。

六、优化前后对比

整体性能提升 292%:

优化后的加载效果对比:

七、性能监控

为了保证平台在后续的迭代过程中,持续保持高性能,我们引入Chrome 开源的 web-vitals 库,结合自研的运行时性能监控埋点(卡顿、崩溃),以及平台的数据可视化能力,实现对前端整体性能的监控。并利用了平台的数据监控预警能力,通过对不同指标的配置告警服务,增加性能指标相关的告警,在性能指标发生异动时,及时发现问题,优化性能,保障了用户使用体验。

八、总结

上面讲了那么多优化方法,都是针对当前项目进行的针对性优化 ,所以我们进行优化时,需要根据具体情况和需求,结合不同的优化策略来达到最佳的性能优化效果。前端性能优化是一个重要的主题,它涉及到许多方面,包括页面加载速度、交互响应时间、资源利用效率等。但不管什么样的优化方式,他们的核心思路都是一致的,因为在用户能看到页面,并且与之交互之前,都是有固定的步骤的,所以优化的核心思路就是:尽可能去掉一些关键步骤、尽可能提前一些重要步骤、尽可能优化某个具体步骤。比如 SSR 相比于 CSR,用户能更快的看到页面,就是去掉了「下载入口index.html,下载并执行 CSS、JS,请求接口」这几个关键步骤,比如上面说的对高优先级资源进行预加载就是提前一些重要步骤,再比如说通过web workers  避免 JS 执行时产生 Long Task就是优化某个具体步骤。以上就是本次性能优化实践的所有内容,希望能对你有所帮助。

BI 数据可视化平台建设(3)—首页性能提升实践的更多相关文章

  1. bi数据可视化平台带来的企业变化

    相信现在互联网的发展,大家有目共睹,在互联网的快速发展下,所产生的数据已经成为庞然大物,各行各业都在进行数据化转型,大数据分析也就成了香饽饽,bi数据可视化平台能够让数据可视化,通过数据分析可以业务人 ...

  2. BI数据可视化工具怎么选?用这款就够了!

    任何一项产品的选择都需要谨慎而全面,BI数据可视化工具的选择就更不用说了.作为企业的IT部门,如果没有良好的BI工具支持,IT部门将会十分容易陷入困境.那么面对多元化的BI工具市场,IT部门该如何选择 ...

  3. 教你如何选择BI数据可视化工具

    本文来自网易云社区. 关于如何选择BI数据可视化工具,总体而言,主流BI产品在选择的时候要除了需要考虑从数据到展现.从公司内到公司外等各种场景,结合前面朋友的回答,还需要考虑以下几点:1:以后的数据处 ...

  4. 基于MaxCompute的媒体大数据开放平台建设

    摘要:随着自媒体的发展,传统媒体面临着巨大的压力和挑战,新华智云运用大数据和人工智能技术,致力于为媒体行业赋能.通过媒体大数据开放平台,将媒体行业全网数据汇总起来,借助平台数据处理能力和算法能力,将有 ...

  5. Superset 0.37 发布——颜值最高的数据可视化平台

    Superset 0.37,增加可视化插件,行级权限控制 使用Superset已经有一段时间,其良好的体验与丰富的图表功能节省了大量的时间.但是对于权限,自定义图表,图表下载,报警邮件一直没有很好的支 ...

  6. 第一篇:Power BI数据可视化概述

    前言 "可视化之工具,可爱者甚蕃.统计学家独爱R,自Python来,世人盛爱matplotlib.余独爱Power BI之出微软而不染(免费),濯Office而不妖(够精简).......& ...

  7. 企业必读:BI数据可视化工具选型

    伴随着大数据时代的到来,企业对数据的需求从"IT主导的报表模式"转向"业务主导的自助分析模式",可视化BI工具也随之应运而生.面对如此众多的可视化BI工具,我们 ...

  8. 第二篇:Power BI数据可视化之基于Web数据的报表制作(经典级示例)

    前言 报表制作流程的第一步显然是从各个数据源导入数据,Power BI能从很多种数据源导入数据:如Excel,CSV,XML,以及各类数据库(SQL Server,Oracle,My SQL等),两大 ...

  9. Web服务端性能提升实践

    随着互联网的不断发展,日常生活中越来越多的需求通过网络来实现,从衣食住行到金融教育,从口袋到身份,人们无时无刻不依赖着网络,而且越来越多的人通过网络来完成自己的需求. 作为直接面对来自客户请求的Web ...

  10. 数据可视化BI平台——CBoard的部署与使用(笔记整理)

    CBoard作为国内自主开发的数据可视化平台,因其方便好用而受到广大用户的使用和好评.现今CBoard有社区版和企业版两个版本,本文所述为社区版的0.4.2版本.注意:所需的一切资源以及相关参考链接都 ...

随机推荐

  1. 拿来即用的下载Excel模板

    模板导出 拿来即用 @PostMapping("/templateExport") @ApiOperation(value = "模板导出", notes = ...

  2. C/S客户端渗透_Proxifier+burpsuite代理客户端http协议数据包+reGeorg构建HTTP隧道代理

    C/S客户端渗透_Proxifier+burpsuite代理客户端https协议数据包 一个月没发文章了实在太忙了,不过学习还是不能落下的,最近要做几个CS客户端的站,需要在终端装个北信源的煞笔内网安 ...

  3. JavaScript 没有“包”

    前言 除了古老的 C/C++,几乎所有的编程语言都有模块系统,都有官方的包管理器.我们一般不自己实现所有的代码,实际应用开发过程中大量使用开源库和框架.这篇文章演示了如何把自己实现的库变成一个包,一个 ...

  4. uv全功能更新:统一管理Python项目、工具、脚本和环境的终极解决方案

    花下猫语:uv 项目自发布起就大受欢迎,目前 Github star 52.6 K,远超过它的同类竞品们.前不久,它的创始人在 X 上披露了一组惊人的数据:uv 曾占据了 PyPI 超过 20% 的流 ...

  5. IDEA问题之“接口路径查询插件【RestfulToolkit】”

    一.场景 只查询Java代码中的路径,这样就可以快速的找到对应的接口 快捷键:Ctrl + \ 二.安装步骤

  6. 浅谈log4j2 CVE-2021-44228

    致谢:此问题由阿里云安全团队的 Chen Zhaojun 发现. 什么是Log4j2 Apache Log4j2 <=2.14.1 版本提供的 JNDI 特性用于配置.日志信息.参数位置时,无法 ...

  7. C#8.0,9.0,10.0常见新语法学习

    顶级语句 (1)一个项目最多只能有一个文件具有顶级语句,就是直接写代码,如果存在多个,则会报错, (2)如果顶级语句和Main共存,则只调用顶级语句 (3)如果没有顶级语句,则必须有Main 简化us ...

  8. 不同版本AutoCAD的ProgID

    AutoCAD产品名 ProgID AutoCAD 2004 AutoCAD.Application.16 AutoCAD 2005 AutoCAD.Application.16.1 AutoCAD ...

  9. Evaluate Division——LeetCode进阶路

    原题链接https://leetcode.com/problems/evaluate-division/ 题目描述 Equations are given in the format A / B = ...

  10. Spring Boot注解之@ComponentScan用法和实现原理

    注解@ComponentScan的作用   @Component注解及其衍生注解@RestController.@Controller.@Service和@Repository都是组件注册注解.@Co ...