文章正文

数据统计在性能检测中的应用

2022-06-14 发布于 · 阅读量:232

前情提要

本文根据 2022.05.28 日,《前端早早聊大会》 的“性能”专场分享整理而来。

​ 本文首先分享了我司自研的性能检测平台百策的基本功能和应用,主要介绍了百策中基于数据统计的能力对指标得分模型及指标区间模型的选择和设计,并最终通过修复工具简化问题的修复,提升页面渲染效率,并反映到指标上。

性能指标的价值

​ 随着互联网环境的飞速迭代,同质化产品的与日俱增,性能的优劣往往是在同代产品中决出的胜负手,同时也是用户体验的重要一环。越来越多的工程和产品对性能的重视程度也在提升,Web 页面渲染相关的指标更是一个网站性能的重要评判标准。

一、百策平台简介

image-20220605194440058

​ 我司自研的性能平台百策可用于检测、分析前台和中后台页面,并提供相关修复方案。其主要的检测功能基于 Chrome LighthousePupeteer 开发,做过前端性能优化的同学对 Lighthouse 并不陌生,其包含了很全面的页面检测功能,那么可能有的同学会问了,为什么有现成的工具还要二次开发呢?直接用他不香吗?我们的答案是香,但是没这么香,下面说下主要原因:

自建的意义

更稳定的服务

​ 我们都知道谷歌的服务例如 Lighthouse 在国内的使用是不稳定的,百策采用的是本地化部署,同其他工具和第三方网站比有更稳定的服务。

数据安全

​ 在我们的应用场景中要测的大部分页面为公司内部站点,采集的数据如果外传,会造成数据安全等问题。

检测标准自定义

​ 可以基于自研的平台做一些自定义的开发,比如现阶段我们结合数据统计的能力去定制不同的性能指标标准。

流程接入

​ 自研的平台可以和公司的其他基建做联动控制,例如接入内部的 CI/CD 工具做发版流程限制。

基础架构

前端主要使用的是 React 、 Antd 、ECharts 等,包含常规页面的展示和性能结果及走势的展示效果。服务端基于 Nest 开发,接入 Sentry 做报警监控,helmet 用于保护系统免受一些 Web 漏洞影响;node-schedule 用于每周定时计算已统计入系统的页面性能,并通过 nodemailer 发送邮件;最主要的检测服务基于 Puppeteer 和 Lighthouse 开发;数据分析模块提供了算分模型及指标区间模型的统计模型,修复优化工具包含了组件式和插件式的图片格式优化功能等。

​ 在之前的分享中我们已经有同学对《 如何从 0 到 1 搭建性能检测系统》 做了分享,这里就不再赘述,后面主要分享下数据分析以及修复优化工具两个模块。

二、指标结果分析

检测结果页

​ 首先来看一下使用百策对目标页面检测完的效果,我们会得到如上图所示的检测结果页,结果页会有性能检测情况以及各项指标的解释说明。

​ 通过刚才检测得出的各项指标结果,我们会得到一系列前端性能指标,诸如影响加载速度的首屏加载时间(FCP)、最大内容绘制间(LCP),影响响应速度的首次输入延迟时间(FID)、可交互延迟时间(TTI)以及视觉稳定性相关的指标,累计偏移量(CLS)等,相信做过性能优化的同学对这些指标并不陌生。 同时还有些公司各业务为了度量匹配不同的性能场景及缺陷, 还通过 PerformanceObserver 等 API 设置不同的自定义指标,诸如用户计时或服务计时等。

​ 那么测得了这么多指标耗时,你的网站性能到底怎么样?如果一个没有做过相关性能优化的同学,或者是你的老板根本不是前端的开发,想关心下你的网站性能怎么样,你要如何回复他们?可能你会罗列一堆耗时、偏移数值等数据,但他们看到这些数值肯定一脸懵逼,根本感知不到你的站点性能到底怎么样,这也是很多性能测试平台的相同的问题,数据并没有做量化处理。

​ 通过指标数值,是不能很直观的看出来要测的网站性能到底怎么样,没有指标结果的量化处理,就没法得到指标的得分和对比标准,根本感知不到检测的结果到底怎么样,没有参考,这些数据在业内的水平就不清楚了。所以为了能对“性能到底怎么样”有更清晰的认知,就要有一套新的标准来度量。

算分模型 & 区间模型

​ 这里我们以 A、B 两个网站为例,分别测得其 LCP 数据。再通过我们设计的2种指标得分模型,可以得到如上的结果。算分模型会得到 S-E 6 个区间,不同区间给不同的评分。区间模型通过指标的耗时情况,针对耗时的不同时间区间落点求得其得分情况。

算分模型

​ 可以看出 A 网站的 LCP 耗时 2125ms 在模型分布中处于中上等水平,在算分模型中的 B 区间,而 B 网站的 8339ms 耗时则提升空间比较大,处于 D 区间内,通过右表也可以看出具体的得分控制情况。

区间模型

​ 在算分模型中,我们根据指标的不同分位数标准来划分从优秀到较差的等级区间,这里采用指标不同分位数(25 百分位数、75 百分位数)的控制方法,同样也可以很明显的观察出 A、B 两个网站的指标所处区间。下面就介绍下我们系统对这两个模型的选择和设计。

数据量化处理

​ 就像我们学生时代一样,老师通常可以通过成绩的得分高低来判断学习的好坏(当然这个也不绝对~)。类比到评分系统而言,一个指标的量化结果评分更能直观的体现站点的优势和瓶颈。

​ 对收集到数据做数据特征的抽象,可以借助统计模型的能力来进行,通过建立对应的统计模型更便于我们对同类数据的分析和处理,再根据分析和处理结论建立数据和结果的映射关系。简而言之建立模型就是一个发现规律,建立关系的过程。

​ 统计模型是利用系统化的符号和数学表达式对问题的一种抽象描述,其建立过程可看作是把问题定义转换为数学问题的过程。所以我们可以通过数学模型的思想来进行后续的分析。类比到数学关系中,这里的 x 就是指标数据 ,y 就是要得到的指标评分。对应刚才提到 S-E 的算分区间,其中 f(x) 就是我们要求解的模型。

建立统计模型主要可以分为以下五个步骤:

第一阶段:定义问题&收集 对性能指标的定量分析就是我们要解决的问题,所以我们就要对该问题进行指标类数据的收集和整理,后面也会讲到本次建立模型所依赖的数据来源及工具。

第二阶段:选择建模方法 这个也是对数据的整理和分析的阶段,通过描述性统计选择合理的建模方法。

描述性统计是指运用制表和分类,图形以及计算概括性数据来描述一组数据特征的各项活动,一般通过数据的平均值、标准差、四分位数等指标结合数据可视化的处理来比较直观的观察数据的特征,比如一些集中、离散、分布的相关趋势。

第三阶段:推导出模型的公式 这一步也是从概念到理论到过程,针对选择的模型,计算出关键参数从而推导出模型公式。

第四阶段:优化和求解 有了对应的数学表达式,适配变量和边界值情况对模型进行调整和优化,并通过不同变量和约束条件进行求解。

第五阶段:结果产出 得出的结果用于后续该类问题的决策,同时也是对模型的一个检验过程,通过预测模型来帮助我们做后续的判断。

定义问题&数据收集

本次收集性能指标的过程主要是采用 HttpArchive + BigQuery 的方式。

HttpArchive: 是一个流行网站的性能数据收集站,通过每个月抓取由 Chrome 用户体验报告(CrUX) 提供的上百万的桌面和移动设备的 URL,并对这些网站的性能数据进行收集和存储。

BigQuery:是 Google 推出的一项 Web 服务,拥有基于 SQL 的企业数据仓库服务的扩展,提供了快速类 SQL 查询和数据管理及可视化的能力。这里我们采用 BigQuery 进行数据拉取。

建立算分模型

​ 在对相对结果的评判中,我们往往采用对整体的分布取标准正态的方法。并且根据 中心极限定理 当在大量随机变量上重复很多次实验时,它们的分布总和将非常接近正态分布,所以以概率统计分布为核心的研究也大都聚焦于正态分布。

​ 其实这个也很好理解,在对日常的统计分析中,很多场景的数据也是符合正态分布的特征的,比如:大部分公司的评级体系,成人的智商的分布、部分投资回报分布等。从这里也可以看出平凡才是大多数,极好和极差都是少数。

​ 正态分布相信大家并不陌生,正态分布也称“常态分布”,又名高斯分布,最早由法国数学家棣莫弗在求二项分布的渐近公式中得到。在数学、物理及工程等领域都有很多应用,在统计学的许多方面有着重大的影响力。其图形两头低,中间高,左右对称,因其曲线呈钟形,因此人们又经常称之为钟形曲线。

​ 建立正态分布的模型主要包括以下五个步骤:

  1. 数据预处理
  2. 样本正态性检验和处理
  3. 正态分布图像拟合
  4. 区间 Z 分布的计算
  5. 确定得分区间及结果

数据预处理

​ 由于网站采集数据的不稳定性,可能会存在因部分数据过大或过小而产生的脏数据。为防止异常数据造成算法精度失真,需要首先剔除空数据及边界异常值。本次样本采集的数据是 2022 年 5 月上旬 FCP 的指标数据,本次样本中脏数据约占总数量的 1.5% 。

image-20220530172851852

​ 可以通过统计 FCP 时长落在某个时间段内的样本数量,绘制样本过滤后数据的分布直方图来观察数据的基本特征。

​ 通过该份样本的直方图可以看出大部分的数据分布在 1000ms ~ 2500ms。

数据正态性检验 & 处理

​ 正态性检验的原假设是“数据服从正态分布”,因此我们要预先对数据进行正态性的检验,符合正态性才能进行基于正态分布的相关分析。如果不符合正态性,则要对数据进行修正转换处理。

​ 通过 IBM. SPSS 工具建立数据分析模型,绘制 Q-Q 图 ,确定数据分布的正态性,除了 Q-Q 图还可以通过茎叶图、直方图、箱式图等来进行判断。

Q-Q 是 Quantile-Quantile 的缩写,也就是分位数-分位数图。因为这个图中横坐标和纵坐标都利用了分位数,横坐标是正态分位数,纵坐标是实际数据的分位数。所以 Q-Q 图的思想就是比较理论分位数和实际分位数的差距,如果理论分位数和实际分位数没什么差别的话,图中所有的点应该都在一条直线上;如果差别大,那就会偏离直线比较大。

​ 根据 Q-Q 图反馈的正态,很明显同直线的偏移比较大,目前的原数据是不能进行后续正态分析的,所以要对数据进行正态化的处理。

​ 根据上文中原数据的分布直方图可以看出,数据是偏态分布的。根据下图可以看出,偏态分布分为两种情况,左偏又叫负偏态,以及右偏又叫正偏态。

可以根据数据的偏态分布表现来确定不同的正态处理方法,下面是一些常见的处理方法:

  • 对数变换:适用于相乘关系的数据、高度偏态的数据
  • 平方根变换:适用于泊松分布(方差与均数近似相等)的数据、轻度偏态的数据
  • 倒数变换 1/x:适用于两端波动较大的数据
  • 反正弦变换:适用于百分比的数据、中度偏态的数据

​ 经过数据转换,结合 Q-Q 图验证,可以采用对原数据取自然对数的方法来进行转换,其转换后的正态 Q-Q 图如下,可以看出通过转换后大部分数据分布在一条直线上。

​ 如下图所示,通过数据转换后的直方图也可以看出,转换后的数据已基本具备正态分布的相关特征。

正态分布拟合

​ 在算分模型中,对图像的拟合一般有两种方法,一种是通过最小二乘法,另一种是通过正态分布计算公式。

​ 最小二乘法的拟合方法通常是采用计算每个样本点到拟合曲线的距离来进行图像拟合。对于指标数据这种数据量比较大的数据源(每个月会有几十万甚至上百万的网站指标数据报告),上述方式的计算量无疑是很大的。所以本次采用正态分布计算公式的方法来进行后续的拟合处理。

​ 如果要建立对应的正态分布方程,需要求解两个关键参数,一个是数学期望,也就是平均数,另一个就是方差。通过这两个关键参数来确定正态分布公式,这也是由正态分布的特征来决定的,描述一个正态分布通常会取 随机变量 X 服从一个 数学期望 为 μ 、方差为 σ^2 的正态分布,记为 N(μ,σ^2)。通过定义可得,一旦均值和标准差确定,正态分布也就确定。

正态分布计算公式:

img

方差计算公式:

1d7eb73fc9d032d41b44ce6c38004aec

本次样本数据的数学期望(平均值) μ = 7.66536 、标准差 σ = 0.55905 ,记做 N(7.66536,0.55905 ^2)。

/**
* 正态分布函数
* @@param x 数据
* @@param mean 平均数
* @@param stdev 标准差
*/
function normalDistributionfun(x, mean, stdev) {
    return (1 / (Math.sqrt(2 * Math.PI) * stdev)) * Math.exp(-1 * ((x - mean) * (x - mean)) / (2 * stdev *               
            stdev));
}
​
/**
* 方差计算函数
* @@param mean 平均数
*/
function stdCalc (mean){
  let total = 0;
  for(let key in data)
      total += data[key];
  const meanVal = total / data.length;
  let SDprep = 0;
  for(let key in data)
      SDprep += Math.pow((parseFloat(data[key]) - meanVal),2);
  const SDresult = Math.sqrt(SDprep/data.length);
  return SDresult
}

​ 再回顾下上面图像转换的过程,首先从源数据的直方图观察出数据特征,然后采用对数转换的形式对原数据进行处理,处理后的数据通过直方图也可以看出已基本具备正态分布的相关特征,后续通过正态分布方程的方法对图像进行拟合。

Z 分布转换

​ 得分等级划分中我们通过 Z 分布的 “ 6σ ” 原则来判断,根据刚才求的数据偏离平均数多少个标准差来确定等分区间。

Z 分布

​ Z 分布又由称作标准正态分布,是正态分布中的一种,其平均数和标准差都是固定的,平均数为 μ = 0,标准差为 σ = 1。每个区间的比例也是固定的,我们可以通过该特性,来对得分区间进行控制。

Z 变换

​ 既然选取了 Z 分布相关特性作后续分析,就要把刚才得到的拟合图像转换为 Z 分布,转换的过程也叫做 Z 变换的过程。

这里我们采用 Z 分布的计算方法来进行指标分布区间的数值计算。Z 分布计算公式 ,Z 值为偏离平均数多少个标准差,均值时间 μ 通过对转换后数据的逆运算约为 1900.36ms。

​ 通过已知的 标准差区间(-3~3),均值时间 μ,以及标准差 σ 可以求得不同区间的时间范围 X。

下面是根据本次样本数据的得出的指标范围和得分列表:

建立阈值区间模型

​ 对于指标的阈值区间判断我们这里参考了 Google CrUX 的标准,通过百分位模型来确定阈值。当观测数据很多时,百分位数的数值相对稳定,通常用来确定一些检验指标和正常值范围。

百分位数:将一组数据从小到大排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数,N% 位置的值称第 N 百分位数。

​ 通过拉取的样本数据,百分位数计算可以通过 percentile.js 来进行,也可以在 Bigquery 中通过百分位数语法的 Sql 实现。75 百分位数是对大多数的网站访问所设定的水平,在 CrUX 中,采用 75 百分位数和 25 百分位数的形式来对指标的阈值区间进行评判,这里是我们针对 LCP、FCP、TTI 指标设置的建议值。

​ 在保证数据受异常值影响较小的情况下,可以根据不同的业务需求设置不同的阈值,比如对性能要求较高的前台页可以采用更加严格的标准,例如低于 35 百分位数即为较差。

​ 如果对某项核心指标或自定义指标比较关心,同样的,可以通过排序得出在同类网站中的百分位数排名占比,以此来判断具体的排名信息。

指标变化趋势

Web 核心指标变化趋势:

​ 这里收集近两年 2020.1- 2022.5 FCPLCPTTI 半年度 75 百分位数指标情况,可以看出随着近些年来终端性能以及前端现代框架的不断更新,以及各大网站对性能的重视度提升,各指标 75 百分位数的耗时数据都有明显降低。

CDN 指标变化:

​ 同时我们还注意到请求中 CDN 的使用率近三年来,每年有近 10 % 的增长,在性能优化的过程中的重视程度也在逐渐提高。我们通过静态资源的前缀(预录入 CDN 地址)匹配,静态资源所在域名下的 IP 地址的个数,来判断静态资源使用情况的详细占比。

三、修复优化工具

​ 在检测出页面的性能瓶颈时,如果要对该页面进行性能的修复和优化,需要有前置知识储备,比如我这个指标该通过什么手段来优化,哪种修复手段可以得到更好的效果,改动了其中代码还需要评估对应的业务影响,通知测试进行流程的回归。这些无疑都增加了在性能优化过程中的阻力和成本,为了解决这些痛点,减轻修复的成本,特别推出了我们内部称作为 “手动”、“半自动”、“全自动” 的修复工具。

“手动” 修复

​ 这里的 “手动” 修复是针对部分指标给出对应的修复建议和相关代码,可以根据建议配置进行优化处理。

image-20220601155027169

“半自动” 修复

​ “半自动”修复是指组件式的优化方案,在需要进行优化处理的地方进行组件引入,并且传入对应参数,每次引用每次生效。

​ 这里以图片为例,图像资源比任何其他资源类型占用更多的字节数,是性能优化的关键一环。由于 WebP 格式的图片相较其他类型图片而言,有体积更小、不失真的特点,所以对图片的优化多采用 WebP 的图片格式。

React Img 组件 & Vue-LazyLoad 组件拓展

​ React Img 组件提供 React 项目中 img 标签包裹, Vue-LazyLoad 组件拓展对 Vue-Lazyload 进行二次包装。处理图片返回格式,根据用户浏览器兼容性提供优化后图片 WebP 格式。

“全自动” 的修复

​ “全自动”修复是指在当前应用中通过 Webpack 插件的形式,在应用中引用后,每次都会生效。

​ Webpack Plugin 插件通过对静态资源的格式和 CDN 白名单地址的匹配进行后续的构建处理。

module.exports = defineConfig({
  transpileDependencies: true,
  publicPath:'./',
  configureWebpack: {
    optimization: {
      minimizer: [
      new ImageminWebpWebpackPlugin({
        config: [{
          // 匹配的文件格式
          test: /\.(jpe?g|png)/,
          // 比例参数控制
          options: {
            quality:  75
          }
        }],
        CDNUrl:['https://sitecdn.xxx.com/']
      }),
    ]
  }
  }
})

​ 在处理过程中主要分为构建、引用、输出三个步骤。与组件处理的类似,同样会判断用户浏览器的兼容性来决定应用哪份文件,如果浏览器兼容 WebP 格式的图片就使用处理后 app.a60c22b2-webp.js 反之则使用 app.a60c22b2.js 文件。

image-20220601162811370

修复效果

image-20220601164214170

image-20220601164234166

​ 这里以某登录页为例,可以看到修复后的图片文件格式由原有的 png 优化为 WebP,图片大小发生了比较显著的变化,从原有的 2.7M 到优化后的 342kb 。

修复结果

image-20220601165916669

​ 这里以 LCP 为例看下修复前后的指标变化情况,LCP 耗时由最开始的 2834ms 缩短至 825ms,从 LCP 指标的正态分布图中可以看出,指标由最原有的 B 区间提升到 S 区间,指标得分在本系统的得分模型中提高了 3 分,整体而言在样本数据的排名中提高了近 30%。

四、后续迭代

​ 下面说下我们后续的迭代方向:

1. 流程控制

​ 首先就是刚才提到的在公司业务中接入流程控制,首先会对上线的版本进行性能预检测,如果不符合对应页面类型的指标阈值限制,则限制发版流程。

2. RUM 接入

​ 通过 SDK 植入的形式,接入监控平台,采集公司真实的用户性能数据,可以更准确的收集到在当前业务场景下的性能情况,以便后续的统计分析和优化。

3. 性能质量监控

​ 定期的抓取线上页面地址并对其进行性能指标测试 ,通过选取不同的特征模型进行异常检测,根据检测的结果来对已上线的页面进行性能稳定性判断。

​ 异常值检测也是 机器学习 中重要的应用之一,采用了非监督学习的方式,检测要测试的样本是否为模型中的离群点。具体的建模和分析方法这里推荐吴恩达老师机器学习第九周的课程 异常检测(Anomaly Detection),里面比较详细介绍了通过高斯分布和多元高斯分布建立模型,推导算法并构建异常检测体系的过程。

4. 更多的工具

​ 后续将提供更多的一站式工具来对网站进行性能优化,开箱即用的工具能大大降低对目标网站性能优化成本的同时,也能为开发者扫除“障碍”,使其更加简单的去提升自己的网站性能,毕竟“懒”才是第一生产力。

五、团队介绍

​ 最后介绍下我们的团队,目前我们团队人数在 90 人左右,是一个年轻富有激情和创造力的前端团队,团队除了日常的业务之外,还在物料体系、工程平台、搭建平台、数据分析及可视化等方向进行技术探索和实战,推动并落地了一系列的内部技术产品,后续也将持续探索前端技术体系的新边界,可以添加我们团队的微信公众号了解更多信息。当然如果你想参与这些有趣好玩的技术,寻找内推机会或者对本次分享有相关问题和建议,也可以添加我的个人微信进行后续讨论。

总结

​ 本文通过样本数据的指标分布建立了两种不同的统计模型:

​ 1、根据 Z 分布的 6σ 原则建立得分模型,来更准确地获取测试网站指标分数情况

​ 2、根据指标的百分位模型为指标优化提供可参考的数据标准

​ 上述两种模型为百策提供了检测能力的拓展,同时也可普适于大多数性能检测系统。另外,建模也是一项富有创造性的工作,对任何问题,“没有唯一正确的模型”。对于同一个问题,我们同样可以从不同角度对其构建出不同的模型进行分析。除了本次分享提到的基于数据统计的应用,我们还可以借助其他学科和领域的相关知识来对前端的能力进行扩充,助力前端生态不断繁荣。

QA

Q:所有的指标都可以采用类似的量化处理吗?

A:目前针对耗时类指标诸如:加载耗时、交互耗时类指标等是可以使用现有的处理方法,但是对于是否开启 Gzip 、是否启用 http2.0 等单向指标判断是不适用这类的量化处理,同时我们也建议对于这种指标采用占比率的方式来进行量化处理。

Q:在对发布流程的限制里,你们的平台采取了什么样的标准来卡发布流程的?

A:在我们的平台中,会根据不同的页面类型制定不同的标准,比如前台的渲染和图片加载较多,为了更好的用户体验,通常会采用更严格的指标标准,比如对核心指标 FCP 、LCP 、TTI、CLS 采用最低 35 分位数的标准进行限制,中后台的页面表单较多,就会采用较低的 25 分位数的标准进行限制。

Q:在算分模型中,除了使用 6 个区间来判断得分情况,还能不能做其他的分数区间控制?

A:除了根据 6σ 的标准进行得分的控制,也可以参考 Z 分位数表(标准正态分布表),指标区间划分在标准正态分布中的所占面积给予不同的判断标准,不同的区间划分可以精确到小数点后两位,通过不同的概率区间可以实现细化的分数控制。

❉ 作者介绍 ❉