《互联网产品的客户端架构·端形态与体验基础》附录 A 客户端指标与体验口径速查

把 FP、FCP、LCP、INP、TBT、CLS 等客户端体验指标的定义、起止点与聚合口径收在一处,说明采样、分位以及端上与服务端口径的差异,列出平均值、幸存者偏差、埋点丢失等统计陷阱,并附一份可直接复用的指标字典模板与一张可直接贴进评审文档的速查表。

为什么需要一份口径速查

同一个词,在不同团队嘴里经常不是同一件事。产品说“首屏慢”,指的是打开页面到看见内容;工程师说“首屏慢”,指的是 LCP 分位变差;服务端说“不慢”,指的是接口 P95 只有几十毫秒。三方都没说谎,但讨论无法收敛,因为指标的起点、终点和分母不同。

这份附录不追求覆盖所有指标,只固定卷一反复使用的那一组:加载类的 FP、FCP、LCP,交互类的 INP、TBT,视觉稳定性的 CLS,以及端上特有的启动、崩溃、卡顿与内存指标。每个指标都写清楚四件事:测量什么、从哪里开始、到哪里结束、分母是谁。口径一旦写死,跨团队讨论才有共同语言。

文中出现的阈值、比例和耗时,除非明确标注为本机输出,都是案例假设值,用来演示判断方法,不是任何真实产品的实测结论。

指标的定义与测量边界

FP 与 FCP

FP(First Paint)是浏览器第一次把任何像素画到屏幕上的时刻,包括背景色。它回答“页面有没有开始响应”,但不回答“用户有没有看到内容”。一个只有白色背景的页面也可以有 FP。

FCP(First Contentful Paint)是第一次绘制文本、图像、Canvas 或 SVG 等内容的时刻。它比 FP 更接近用户感知,但仍然只代表“有东西出现”,不代表主要内容出现,也不代表可以交互。

两个指标的边界都在“首次绘制”,因此容易受字体、首屏骨架和占位图影响。一个立即渲染骨架屏的页面 FCP 很好,用户却可能仍要等很久才看到真实内容。用 FCP 单独做考核,会诱导团队把骨架屏做得更早、更漂亮,而不是让真实内容更早到达。

LCP

LCP(Largest Contentful Paint)是视口内最大内容元素的绘制时刻。它通常对应首屏主图、大标题或文章正文块,因此比 FCP 更接近“主要内容可见”。

LCP 有三个必须写进口径的细节:

  • 候选元素会随页面加载变化。先出现的大标题可能被后加载的主图取代,最终 LCP 取的是最后一个候选的绘制时间。
  • 用户在页面上的首次交互会终止 LCP 的候选更新。也就是说,用户等不及点了一下,后面的内容再大也不再计入 LCP。
  • 页面进入后台或不可见时,LCP 停止记录。单页应用切换路由不会自动重置 LCP,需要按路由重新采集。

最后一个细节最容易被忽略:在一个长会话里只取一个 LCP,会把第二个页面的首屏算成“很快”,因为计时起点还是应用启动。按路由采集时,起点应是路由切换开始渲染的时刻,终点是该路由主要内容绘制完成的时刻。

INP

INP(Interaction to Next Paint)衡量用户交互到下一帧绘制的延迟。它观察页面生命周期内的多次交互,取一个高分位作为代表值,而不是只看第一次输入。与它容易混淆的是已经退场的 FID:FID 只测第一次输入的响应延迟,不关心后续绘制,也不关心慢交互。

INP 的口径难点在“交互”的边界。键盘输入、点击、触摸都算;滚动和悬停通常不算独立交互,但会参与帧的绘制。若一个点击触发了网络请求,INP 只等到下一帧绘制,不等请求完成。把“点击到数据回来”当成 INP,会得到一个完全不同、也无法与行业口径比较的数字。

TBT 与 TTI

TBT(Total Blocking Time)是 FCP 到 TTI 之间,所有长任务超过 50 毫秒部分的累加。它是一个实验室指标,依赖可控的加载条件,适合做版本间对比,不适合直接代表真实用户的某一次体验。

TTI(Time to Interactive)表示页面已经完成有用的首次绘制、主线程足够空闲、能够稳定响应输入的时刻。TTI 的判定依赖长任务窗口,不同工具的实现细节可能不同,因此跨工具比较前要确认算法版本。

TBT 与 INP 的关系常被误解:TBT 高通常意味着主线程被占满,INP 也可能变差;但 TBT 低不代表 INP 一定好,因为交互期间的长任务、事件处理逻辑和渲染成本仍可能拖慢单次响应。实验室看 TBT,真实用户看 INP,两者不能互相替代。

CLS

CLS(Cumulative Layout Shift)衡量页面内容的意外位移。它由影响区域与位移距离共同决定,并按会话窗口聚合,避免把长时间页面里的偶发位移无限累加。

口径里必须排除用户主动触发的位移,例如用户点击后展开的菜单、用户滚动后出现的吸顶栏。把这些算进 CLS,会让“交互丰富”的页面被误判为不稳定。另一个常见错误是把字体加载导致的文本重排当成正常现象:只要用户没有预期内容会移动,它就应计入。

端上特有指标

Web 指标之外,原生与混合客户端还有一组必须单独定义的口径:

指标测量对象关键边界
冷启动时长进程不存在到首帧可交互起点是系统创建进程,终点是首屏可操作
温启动时长进程存活但页面被回收起点是回到前台,终点是页面恢复可操作
热启动时长进程与页面都存活只测前台切换,不测业务恢复
崩溃率会话或用户维度必须声明分母是会话、用户还是启动次数
ANR 率主线程长时间无响应不同系统的判定阈值不同,不能直接横比
慢帧与冻结帧帧耗时超过阈值阈值要写进字典,不能口头约定
内存峰值前台峰值与后台峰值要区分虚拟内存、常驻内存与系统压力指标
OOM 率被系统因内存被杀与普通崩溃分开统计,否则归因会失真

这些指标没有统一的行业定义,更容易出现“各说各话”。把它们写进指标字典,比争论哪个数字更准确更重要。

一张关系表

指标类型起点终点主要回答
FP实验室/真实用户导航开始首次任意绘制页面是否开始渲染
FCP实验室/真实用户导航开始首次内容绘制用户是否看到内容
LCP真实用户为主导航或路由开始最大内容元素绘制主要内容是否可见
INP真实用户交互输入下一帧绘制交互是否跟手
TBT实验室FCPTTI主线程被阻塞多久
CLS真实用户为主页面可见页面隐藏内容是否意外跳动
冷启动真实用户/实验室进程创建首屏可操作应用打开是否快
崩溃率真实用户会话或启动开始会话结束应用是否稳定

采样、聚合与分位

分母决定含义

“成功率 99%”本身没有意义,必须问分母是什么。以请求为分母,重试会把分母放大;以会话为分母,一个会话里的多次失败只算一次;以用户为分母,重度用户会稀释问题。客户端指标尤其容易在这里出错,因为一次页面访问可能产生几十个请求、多次交互和多个路由。

建议每个指标都显式写出三层分母:事件层(多少次请求/交互)、会话层(多少次访问)、用户层(多少个独立用户)。排查阶段看事件层,评估影响面看会话层,做长期趋势看用户层。三层都看,才能避免“请求成功率很高,但受影响用户很多”这类误判。

分位而不是平均

体验指标天然是长尾分布。多数用户很快,少数用户极慢,平均值会被两端拉扯,既不像典型用户,也不像最差用户。常用做法是同时看 P50、P75、P95:P50 代表典型体验,P75 接近“多数人可接受”的边界,P95 暴露尾部问题。

具体用哪个分位做预算,是团队约定,不是自然规律。重要的是固定下来,并在指标字典里写清楚。今天用 P75、明天用 P90,趋势图就会失去意义。

分位不能求平均

一个常见错误是把多个维度的 P75 求平均,得到“总体 P75”。分位数不具备可加性,正确的做法是保留原始分布或直方图,在总体样本上重新计算分位。若只能拿到各维度的分位值,至少不要把它们平均后当成总体指标,而应标注为“维度分位的均值”,并说明它不是总体分位。

同理,按天 P75 的周平均也不是周 P75。看板可以做平滑,但不能把平滑后的数当成原始口径对外汇报。

样本量与尾部

分位越靠尾部,需要的样本越多。P95 在小样本上会剧烈跳动,P99 更容易被个别极端值支配。展示分位时同时展示样本数,是最低要求;样本不足时,宁可退回 P50/P75,也不要用一个不稳定的 P99 做结论。

另一个细节是采样率。端上为了控制成本,常按会话或用户采样。采样后的分位仍然可以估计总体分位,但前提是采样与服务端无关,且各版本的采样率一致。如果新版本降低了采样率,趋势图上的“改善”可能只是样本构成变了。

端上采样与服务端采样的差异

维度端上采样服务端采样
采样单位会话、用户、设备请求、连接、追踪 ID
丢失环节应用被杀、离线、上报失败日志管道、采样丢弃
偏差来源设备性能、网络、版本分布流量结构、重试、爬虫
适合回答真实体验、崩溃、卡顿接口耗时、错误率、容量
不适合回答服务端容量与成本用户感知与端上渲染

端上数据和服务端数据不能互相替代。端上 LCP 包含了网络、资源加载、解析与渲染;服务端只看到请求处理的一段。把服务端接口耗时当成首屏耗时,会系统性低估问题。

端上口径与服务端口径的差异

同样是“一次请求的耗时”,两边的计时边界不同。服务端通常从收到完整请求开始,到写出响应结束;端上从发起请求开始,包含 DNS、连接、TLS、排队、传输和等待,直到响应体读完。弱网下,端上耗时可能是服务端耗时的数倍,这不是谁算错了,而是测的不是同一段。

维度端上口径服务端口径
计时起点用户动作或导航开始请求到达或连接建立
计时终点像素绘制或交互完成响应写出完成
失败样本可能完全丢失通常有日志
时钟设备时钟,可能漂移服务器时钟,可校准
网络真实且多变机房内相对稳定
重复重试、双端上报重试、代理重放
版本新旧长期共存通常同时一致

这张表的用途不是比较谁更准,而是提醒:当端上说“慢”、服务端说“快”时,先确认两边测的是不是同一段路径。多数争论在把边界画出来后就会消失。

常见统计陷阱

平均值掩盖尾部

案例假设值:某页面加载耗时平均 1.2 秒,看起来可以接受;但 P95 是 8 秒,意味着每二十次访问就有一次明显卡顿。平均值把一次 30 秒的极端值摊薄了,也把大量 0.8 秒的快速样本当成了“整体不错”的证据。

处置方式很简单:默认看分位,平均值只作为辅助;同时在图表上标出样本数和尾部截断规则。

幸存者偏差

只有成功加载并成功上报的会话才会进入 LCP 样本。白屏、崩溃、用户立刻退出的会话往往没有指标,于是“留下来的样本”看起来都不错。案例假设值:白屏率 2%,但白屏会话全部缺失 LCP,报表上的 LCP 仍然很好看。

处置方式是给每个体验指标配一个“应上报数”分母,例如页面曝光数或启动数,用上报覆盖率反推缺失。缺失率本身就是一个指标,不能只在上报成功的数据里做分析。

埋点丢失

端上埋点可能因为进程被杀、离线、队列满、上报失败而丢失。丢失往往不是随机的:低端机更容易被杀,弱网更容易失败,出问题的版本更容易崩溃。于是丢失本身带有偏差,直接把剩余样本当成全体,会系统性高估体验。

处置方式包括:本地队列持久化、下次启动补报、关键事件双通道、用服务端请求数做交叉校验。补报数据要带原始时间戳和补报标记,避免把“补报时刻”当成“发生时刻”。

重复与双端上报

同一个事件可能被 Web 容器和原生容器各上报一次,也可能因为重试被重复发送。重复样本会让某些路径的权重翻倍,尤其是失败重试多的路径,恰好是最需要准确归因的路径。

处置方式是在事件里带稳定的去重键,并在入库时按去重键聚合;同时监控重复率,把它当成数据质量指标。

后台与不可见页面

页面进入后台后,浏览器会节流定时器、暂停渲染,LCP 和 CLS 也停止更新。如果把后台停留时间算进“页面加载时长”,会得到大量虚假的慢样本。反过来,如果只在页面隐藏时上报,又会漏掉那些一直不隐藏的长会话。

处置方式是明确“可见时长”和“墙钟时长”两个口径,并在指标字典里写清楚用哪一个。涉及首屏的指标,一律只统计可见阶段。

口径漂移

口径漂移很少以“改定义”的形式出现,更多是悄悄发生的:新版本换了采集 SDK、改了路由结构、把某个页面从 SSR 改成 CSR、调整了采样率。指标曲线变了,团队却以为体验变了。

处置方式是给指标字典加版本号,采集实现变更时记录变更点,并在看板上标注发布时间。跨版本比较前,先确认口径一致;不一致时,宁可分段看,也不要连成一条线。

选择偏差

只统计内测用户、只统计新设备、只统计某个渠道,都会得到有偏的结论。案例假设值:内测用户的设备普遍较新,LCP 比全量用户好一截;如果按内测数据定预算,上线后必然超标。

处置方式是明确样本范围,并按设备档位、网络类型、版本、渠道做分层。总体指标用于汇报,分层指标用于决策。

指标字典模板

指标字典不需要复杂工具,一段固定结构的文本就能避免大部分争论。建议每个指标至少包含以下字段:

指标名:
英文名 / 缩写:
一句话定义:
单位:
计时起点:
计时终点:
采集位置(端上 / 服务端 / 实验室):
聚合方式(P50 / P75 / P95 / 均值):
分母(事件 / 会话 / 用户):
分层维度(版本 / 设备 / 网络 / 路由):
预算或阈值:
已知偏差与缺失:
负责人:
口径版本与变更记录:

填写示例

以 LCP 为例,一份可用的条目大致如下:

字段示例内容
指标名主要内容可见时间
英文名Largest Contentful Paint
一句话定义视口内最大内容元素完成绘制的时刻
单位毫秒
计时起点导航开始或路由切换开始
计时终点最大内容元素绘制完成
采集位置端上真实用户
聚合方式按天取 P75
分母页面曝光会话
分层维度版本、设备档位、网络类型、路由
预算或阈值案例假设值:P75 不超过 2.5 秒
已知偏差白屏与崩溃会话缺失;后台页面停止记录
负责人客户端性能小组
口径版本v1,随采集 SDK 变更复核

这张表里的 2.5 秒是案例假设值,不是行业标准。团队应根据自己的产品类型、设备分布和用户预期确定预算,并把依据写进决策记录。

速查表

指标回答的问题单位起点终点常用聚合主要偏差
FP是否开始渲染毫秒导航开始首次任意绘制P75背景色也会触发
FCP是否出现内容毫秒导航开始首次内容绘制P75骨架屏会美化结果
LCP主内容是否可见毫秒导航/路由开始最大内容绘制P75交互终止更新;后台停止
INP交互是否跟手毫秒输入事件下一帧绘制高分位不包含请求完成时间
TBT主线程阻塞程度毫秒FCPTTI实验室中位数依赖可控加载条件
CLS内容是否跳动无量纲页面可见页面隐藏会话窗口用户触发的位移应排除
冷启动打开是否快毫秒进程创建首屏可操作P75/P95设备与系统差异大
崩溃率是否稳定百分比会话/启动开始会话结束按版本分桶分母定义必须固定
慢帧率滚动是否流畅百分比页面可见页面隐藏按设备分层帧率上限随设备不同
内存峰值是否接近上限MB页面进入页面退出P95系统压力指标不等于占用

使用这份速查的三个场景

第一个场景是定预算。产品、设计和工程一起把候选指标过一遍,删掉回答不了当前问题的指标,给留下的每个指标填写字典字段。预算不是拍一个数字,而是回答“超过多少就算失败、失败后谁负责”。

第二个场景是排查。先确认症状对应哪个指标,再确认该指标的起点、终点和分母,最后才看数据。顺序反过来,很容易拿着一份口径不对的报表找错方向。

第三个场景是评审。附录 C 的评审清单会引用这里的指标字典;没有字典的团队,评审时只能讨论“感觉快不快”,无法判断质量预算是否可执行。

常见错误与边界

  • 把 FP 或 FCP 当成首屏完成。它们只说明“有东西出现”,不说明主要内容可见。
  • 用平均值汇报体验。平均值既不代表典型用户,也不代表最差用户。
  • 把多个维度的 P75 求平均。分位不可加,必须回到原始分布重算。
  • 用服务端接口耗时代表端上首屏。两边计时的起止点不同,网络与渲染都不在服务端口径里。
  • 只统计上报成功的样本。白屏、崩溃、立即退出的会话恰恰是最需要被看见的部分。
  • 把补报时间当成发生时间。补报数据必须保留原始时间戳。
  • 不写分母。会话、用户、请求三种分母会给出三个不同的“成功率”。
  • 口径变更不留记录。曲线突变时,无法区分是体验变了还是采集变了。
  • 把案例假设值当成行业标准。阈值要结合产品事实,并写进决策记录。
  • 指标越多越好。回答不了决策问题的指标,只会增加维护成本。

小结

指标的价值不在数字本身,而在它固定了一套可复现的观察方式。定义清楚起点、终点、分母和聚合方式,跨团队才有共同语言;保留原始分布、标注样本量与缺失,才能避免被平均值和幸存者偏差误导。

这份速查表可以直接贴进评审文档,也可以作为指标字典的起点。真正要落到团队里的,不是这张表,而是“每个指标都有负责人、有口径版本、有变更记录”的习惯。下一份附录把这些指标用到具体症状上,给出端上问题的排查顺序。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「books」更多文章

  1. 《互联网产品的 AI 架构·平台化与治理》附录 C 平台化评审清单
  2. 《互联网产品的 AI 架构·平台化与治理》附录 B 能力目录与配额字段速查
  3. 《互联网产品的 AI 架构·平台化与治理》附录 A 治理角色与职责速查