性能测试工具 如何有效度量前端性能

Kilmer · 2023年02月10日 · 最后由 测试新人 回复于 2023年11月08日 · 63669 次阅读
本帖已被设为精华帖!

目标:

  • 从用户角度明确前端 Web、H5 性能测试需要重点关注的内容;
  • 根据关注内容明确性能测试过程中的性能评判指标和建议的阈值范围;
  • 整理性能测试过程中各性能评价指标的收集方法;
  • 明确性能测试完毕后的测试结果展现形式;

质量模型:

用户在访问网页时,网页的性能好坏给用户带来了什么,或者说用户需要的高性能是什么样的,又或者说是用户能感知到的性能是什么?

# 用户关注的内容 意义
1 是否正在发生? 当我输入 URL 并回车时,导航到底有没有发生呢?背后的服务器是不是有响应呢?
2 是否有用? 我访问页面时,页面是否快速展现了用户最关注的内容或者是展现了产品最需要了解的内容?
3 是否可用? 当页面第一次展现出可交互的元素时,用户的使用是否是有效的?
4 是否令人愉悦的? 用户与页面的交互是否流程、自然?不会出现延迟和卡顿?

根据用户感知的性能,我们可以初步确认前端 Web,H5 性能测试的维度、方向是以下内容:

# 维度 含义 用户关注的内容
1 感知加速度(Perceived load speed) 页面在屏幕上加载并渲染出所有视觉元素的速度 是否正在发生?
是否有用?
2 加载响应度(Load responsiveness ) 为了使组件对用户交互作出快速响应,页面加载和执行任何所需 JavaScript 代码的速度。 是否可用?
3 运行响应度(Runtime responsiveness) 页面在加载后,对用户交互的响应速度 是否令人愉悦?
4 视觉稳定性(Visual stability) 页面上的元素是否会出现让用户感到意外的偏移,并对用户交互造成潜在的干扰? 是否有用?
是否可用?
是否令人愉悦?
5 平滑度(Smoothness) 过渡和动画在页面状态切换的过程中是否具有稳定的帧速率和顺滑的流动性? 是否可用?
是否令人愉悦?

根据用户对性能的感知和性能的测试维度,我们可以确认前端 Web、H5 性能测试的重要指标:

# 指标 含义 优先级 测试维度
1 FCP First Contentful Panit:首次内容绘制

测量页面从开始加载到页面内容的任何部分在屏幕上完成渲染的时间。
P0 感知加速度
2 LCP Largest Contentful Paint:首次最大内容绘制

测量页面从开始加载到最大文本块或图像元素在屏幕上完成渲染的时间
P0 感知加速度
3 FID First Input Delay:首次输入延时

测量从用户第一次与您的网站交互(例如当他们单击链接、点按按钮或使用由 JavaScript 驱动的自定义控件)直到浏览器实际能够对交互做出响应所经过的时间。
P3 加载响应度
4 TTI Time To Interactive:可交互时间

测量页面从开始加载到视觉上完成渲染、初始脚本(如果有的话)完成加载,并能够快速、可靠地响应用户输入所需的时间。
P1 加载响应度、运行响应度
5 TBT Total Blocking Time 总阻塞时间

测量 FCP 与 TTI 之间的总时间,这期间,主线程被阻塞的时间过长,无法作出输入响应。
P1 加载响应度、运行响应度
6 CLS Cumulative Layout Shift 累积布局偏移

测量页面在开始加载和其生命周期状态变为隐藏期间发生的所有意外布局偏移的累积分数。
P2 视觉稳定性、平滑度

在前端 Web、H5 的性能测试过程中,只感觉性能指标进行测试时不够的,还需要确保功能的准确性和兼容性

# 指标 含义 测试维度
1 AF Accurate Function
功能准确

测量页面全部加载完成后,当前页面的展现和交互功能是否符合产品设计和交互逻辑
2 CF Compatible Function
功能兼容

测量同一个页面在不同环境中(例如:网络环境,软件环境、硬件环境)中的功能、性能表现

综上所述,我们收敛出前端性能测试的质量模型

指标阐述和使用

FCP:

什么是 FCP?

首次内容绘制 (FCP) 是测量感知加载速度的一个以用户为中心的重要指标,因为该项指标会在用户首次在屏幕上看到任何内容时,在页面加载时间轴中标记出相应的点,迅捷的 FCP 有助于让用户确信某些事情正在进行。

测量什么?

测量页面从开始加载到页面内容的任何部分在屏幕上完成渲染的时间。

建议指标阈值

JS 代码提取

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
    console.log('FCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'paint', buffered: true});

更多内容:

https://web.dev/fcp/

LCP:

什么是 LCP?

最大内容绘制 (LCP) 是测量感知加载速度的一个以用户为中心的重要指标,因为该项指标会在页面的主要内容基本加载完成时,在页面加载时间轴中标记出相应的点,迅捷的 LCP 有助于让用户确信页面是有效的。

测量什么?

测量页面首次开始加载的时间点来报告可视区域内可见的最大图像或文本块完成渲染的相对时间。

建议指标阈值

JS 代码提取

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
    console.log('FCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'paint', buffered: true});

更多内容:

https://web.dev/lcp/

FID:

什么是 FID?

首次输入延迟 (FID) 是测量加载响应度的一个以用户为中心的重要指标,因为该项指标将用户尝试与无响应页面进行交互时的体验进行了量化,低 FID 有助于让用户确信页面是有效的。

测量什么?

测量从用户第一次与页面交互(例如当他们单击链接、点按按钮或使用由 JavaScript 驱动的自定义控件)直到浏览器对交互作出响应,并实际能够开始处理事件处理程序所经过的时间。

A 时间点:页面已经加载出了可交互的元素;

B 时间点:可交互的元素背后的 JS 代码开始在主线程中进行处理;

C 时间点:用户与可交互的元素进行交互;

D 时间点:可交互元素背后的 JS 代码处理完成;

所以当用户在时间点 C 的时候与元素进行交互时,并不能第一时间得到交互的反馈,需要等到 D 时间后才会得到交互的反馈,D-C = FID


在整个页面的加载渲染过程中,让用户第一时间发现"立即抢购"按钮并产生交互(点击时),便产生了 FID 的时间。

建议指标阈值

JS 代码提取

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    const delay = entry.processingStart - entry.startTime;
    console.log('FID candidate:', delay, entry);
  }
}).observe({type: 'first-input', buffered: true});

更多内容:

https://web.dev/fcp/

TTI:

什么是 TTI? 

测量页面从开始加载到视觉上完成渲染、初始脚本(如果有的话)完成加载,并能够快速、可靠地响应用户输入所需的时间。

测量什么?

测量页面从开始加载到主要子资源完成渲染,并能够快速、可靠地响应用户输入所需的时间。

  1. 沿时间轴正向搜索时长至少为 5 秒的安静窗口。(安静窗口的定义:没有长任务(大于 50 毫秒)且不超过两个正在处理的网络 GET 请求。)
  2. 沿安静窗口的开始时间在时间轴上反向查找最近一个长任务的结束时间点,即为 TTI。如果从 FCP 开始没有大于 50ms 的长任务,TTI 则与 FCP 值相同。
  3. 图例 1:
    1. T1 时间范围内,存在 LongTask 且网络请求>2
    2. T2 时间范围内,不存在 LongTask 但网络请求>2
    3. T3 时间范围内 (持续 5 秒),不存在 LongTask 且网络请求<=2,因此我们认为 T3 时间内整个 UI 呈现的安静窗口 ## 建议指标阈值 阈值的计算为开始加载到 TTI 出现的时长

更多内容:

https://web.dev/fcp/

TBT:

什么是 TBT? 

测量 FCP 与 TTI 之间的总时间,这期间,主线程被阻塞的时间过长,无法作出输入响应。

测量什么?

总阻塞时间 (TBT) 指标测量 FCP 与 TTI 之间的总阻塞时间,这期间,主线程被阻塞的时间过长,无法作出输入响应。

TBT 是 TTI 的一个出色的配套指标,因为 TBT 有助于量化在页面交互性变为可靠前,不可交互程度的严重性

浏览器页面加载主线程中存在 5 个任务其中 3 个超过 50ms

虽然在主线程上运行任务的总时间为 560 毫秒,但其中只有 345 毫秒被视为阻塞时间。
T1 = TTI-FCP
TBT = T1 范围内的 long task 时间总和-TI 范围内的 long task 个数 *50ms


建议指标阈值

为了提供良好的用户体验,网站在普通移动硬件上进行测试时,应该努力将总阻塞时间控制在 300 毫秒以内。

更多内容:

https://web.dev/fcp/

CLS:

什么是 CLS? 

布局偏移示例

测量什么?

测量整个页面生命周期内发生的所有意外布局偏移中最大一连串的布局偏移分数。

只要可视区域中可见元素的起始位置在两帧之间发生了变更,这样的元素认定为不稳定元素。

只有当元素的起始位置发生变更时才算作布局偏移,新元素添加到 DOM 中或者改变元素的大小则不算布局偏移。

影响分数:

第一帧中文本元素占比 50%,在第二帧中文本元素其实未知下移 20%,文本元素的总可占比变为 70%

距离分数:

距离分数指的是任何不稳定元素在一帧中位移的最大距离(水平或垂直)除以可视区域的最大尺寸维度(宽度或高度,以较大者为准)。

第二帧中位移距离在高度中占比 20%

布局偏移分数=影响分数 0.7* 距离分数 0.2 = 0.14

建议指标阈值

JS 代码提取

let clsValue = 0;
let clsEntries = [];

let sessionValue = 0;
let sessionEntries = [];

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    // 只将不带有最近用户输入标志的布局偏移计算在内。
    if (!entry.hadRecentInput) {
      const firstSessionEntry = sessionEntries[0];
      const lastSessionEntry = sessionEntries[sessionEntries.length - 1];

      // 如果条目与上一条目的相隔时间小于 1 秒且
      // 与会话中第一个条目的相隔时间小于 5 秒,那么将条目
      // 包含在当前会话中。否则,开始一个新会话。
      if (sessionValue &&
          entry.startTime - lastSessionEntry.startTime < 1000 &&
          entry.startTime - firstSessionEntry.startTime < 5000) {
        sessionValue += entry.value;
        sessionEntries.push(entry);
      } else {
        sessionValue = entry.value;
        sessionEntries = [entry];
      }

      // 如果当前会话值大于当前 CLS 值,
      // 那么更新 CLS 及其相关条目。
      if (sessionValue > clsValue) {
        clsValue = sessionValue;
        clsEntries = sessionEntries;

        // 将更新值(及其条目)记录在控制台中。
        console.log('CLS:', clsValue, clsEntries)
      }
    }
  }
}).observe({type: 'layout-shift', buffered: true});


可以使用灯台工具测试 CLS

更多内容:

https://web.dev/fcp/

测试环境:

环境 内容
网络 4g,5g,wifi
系统 android,iOS
缓存 首开,二开
状态 登陆,未登录
平台 微信、小程序、浏览器

测试流程:

性能专项

对售卖流程中的某环节进行性能专项人工测试,各环境场景下各前端性能指标提取!

注意,我们建议:

  1. 新的核心的重要的且对前端性能有明确要求的业务出现时进行性能专项测试。而不是上线一段时候后再找时间补足性能专项测试。
  2. 性能专项会面临一个问题是,根据任务排期和上线时间点的要求,专项测试的进入会对上线时间点产生冲击,因为新页面的上线从原来的功能测试->功能测试 + 性能专项。 #### 性能监控

对核心的重要的前端业务的某环节进行持续、周期性能提取,分析,报告。

注意,我们建议:

  1. 性能专项测试需要同步开启性能监控(因为只有核心重要且有性能要求的前端业务才会做性能专项测试)
  2. 不建议直接在页面中追加性能埋点直接进行性能监控。(因为性能埋点本身也是需要进行验证的,如果性能埋点存在问题,那么性能监控就没有意义。)

性能专项流程

需求评审阶段

  1. QA 需要判断出是否需要做性能专项测试。如果需要和产品确认性能的要求。

    开发设计阶段

  2. QA 需要将产品的性能要求翻译成具体的性能指标并和开发确认。

  3. QA 与开发确认性能埋点指标范围、上报信息、埋点可提取性。

    测试设计阶段

  4. QA 需要梳理当前性能专项测试对应的场景,工具、方法,设备,报告。

    测试评审阶段

  5. QA 明确已经确认的性能专项指标、场景、工具、方法、设备、报告的有效性。

    测试阶段

  6. QA 进行性能专项指标的提取、汇总。

  7. QA 测试过程中发现性能问题时,需要及时反馈、终止性能测试,待性能问题修复后继续进行测试。

  8. QA 对性能监控依赖的性能埋点的有效性进行确认。

    性能监控流程

性能监控依赖的性能埋点发生新增或变化时,不需要进行性能专项测试,需要做到的是在测试阶段功能测试后确认性能埋点的有效性。

性能监控≠性能专项测试

性能监控

对性能埋点的期望:

我们希望支撑性能监控的性能埋点能够体现出以下信息:

1、页面名称

2、业务流程名称

3、页面版本

4、环境:网络、平台、系统、是否发生登陆等

通过以上信息在性能监控中反应出特定流程下特定页面的特定版本的各环境场景的性能表现。

共收到 12 条回复 时间 点赞

@chenhengjie123 求加精~

Kilmer 如何测量 web 页面加载时间 中提及了此贴 02月10日 10:17

👍 有用,一下就看明白了

😂 确实写的可以

陈恒捷 将本帖设为了精华贴 02月10日 14:01
Kilmer 回复

不错的分享,已加精

写得太棒了,刚好有这方面的需求痛点,受教!

mark 细致,看得出来是真实实践经验

神雕 回复

真丶实践

在时间过程中,其实发现很多前端页面组件加载时序问题. 按照各指标的要求,调整后用户视角的体验提升很多 。

请问下, 针对不同的平台和系统,是如何进行测试的呢 ?比如在安卓和 ios,以及小程序,在移动端的话, 是如何观测性能数据的呢 ?

大葵 回复

提供两种思路:

1、你可以调查一下 “chrome://inspect/#devices” 和 “微信端调试 H5 页面” 这两个内容

2、文章中其实重点是提供的度量前端性能的维度和指标,所以对于测试人员来说,这里有个很重要的东西就是 “有没有人人能够指出在做前端性能测试的时候应该从哪些维度来度量,这些维度是否合理”,如果这些维度合理的话,至于怎么提取就很容易了,不论是 PC 和移动设备,浏览器内核都是具备调试协议和 SDK 的,可以让开发人员按照你提供的维度在代码中进行提取并上报。

我也是测试 web 比较多,第一次看到有人总结,太好了

fid 计算这里是在哪里看的? chrome 里没找到

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册