编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • 性能优化实践

    • README
    • 公共方法论

      • 性能工程总论原理
      • 跨平台指标体系
        • 01.为什么需要统一的指标体系
          • 1.1 指标混乱的代价
          • 1.2 一个好指标的五个特征
        • 02.三种指标视角
          • 2.1 USE 模型 — 资源视角
          • 2.2 RED 模型 — 请求视角
          • 2.3 APDEX / Web Vitals — 用户感知视角
          • APDEX (Application Performance Index)
          • Google Web Vitals(Web 端事实标准,可借鉴到客户端)
          • 客户端等价指标(本专栏定义)
          • 2.4 三视角组合使用
        • 03.分布与百分位
          • 3.1 为什么均值是性能领域的谎言
          • 3.2 百分位的物理含义
          • 3.3 直方图与 HDR 直方图
          • 3.4 抖动与稳定性指标
        • 04.跨平台核心指标矩阵
          • 4.1 CPU 类指标
          • 4.2 内存类指标
          • 4.3 渲染类指标
          • 4.4 网络类指标
          • 4.5 启动类指标
          • 4.6 稳定性类指标
        • 05.指标的边界与陷阱
          • 5.1 高 Goodhart's Law 风险指标
          • 5.2 平台口径差异
          • 5.3 采样误差与置信区间
        • 06.从指标到 SLO
          • 6.1 SLI / SLO / SLA 的关系
          • 6.2 错误预算
          • 6.3 端侧 SLO 的特殊性
        • 07 行业 SLO 基准对照
          • 7.1 启动时间基准
          • 7.2 渲染与卡顿基准
          • 7.3 内存与崩溃基准
          • 7.4 网络性能基准
          • 7.5 头部 App 公开过的真实数字
          • 7.6 反例:失败的优化案例
        • 一句话总结
      • 性能求证方法论
      • 数据采集与观测
      • 归因方法与火焰图
      • 性能预算防劣化
      • 性能体系全景图
      • 性能优化误区集
    • 体系建设篇

    • 资源专项篇

    • 流水线专项

    • 业务专项篇

    • 交付防御篇

  • 程序编程原理

  • 稳定性与可靠性

  • 工程化与运维

  • 方案设计思想

  • 专栏
  • 性能优化实践
  • 公共方法论
杨充
2026-05-27
目录

跨平台指标体系

# 跨平台性能模型与指标体系

📊 学习成本预估 | 难度:⭐⭐⭐⭐(4/5)| 阅读:约 25 分钟 | 实操:1 小时 🔗 前置阅读:卷零·01 | ➡️ 后续延伸:卷一·01, 卷一·03

本文定义专栏的统一指标语言。所有性能议题(启动、卡顿、内存、网络…)必须能在本文定义的指标体系中找到对应位置,否则视为"伪议题"。

# 目录介绍

  • 01.为什么需要统一的指标体系
    • 1.1 指标混乱的代价
    • 1.2 一个好指标的五个特征
  • 02.三种指标视角
    • 2.1 USE 模型 — 资源视角
    • 2.2 RED 模型 — 请求视角
    • 2.3 APDEX / Web Vitals — 用户感知视角
    • 2.4 三视角组合使用
  • 03.分布与百分位
    • 3.1 为什么均值是性能领域的谎言
    • 3.2 百分位的物理含义
    • 3.3 直方图与 HDR 直方图
    • 3.4 抖动与稳定性指标
  • 04.跨平台核心指标矩阵
    • 4.1 CPU 类指标
    • 4.2 内存类指标
    • 4.3 渲染类指标
    • 4.4 网络类指标
    • 4.5 启动类指标
    • 4.6 稳定性类指标
  • 05.指标的边界与陷阱
    • 5.1 高 Goodhart's Law 风险指标
    • 5.2 平台口径差异
    • 5.3 采样误差与置信区间
  • 06.从指标到 SLO
    • 6.1 SLI / SLO / SLA 的关系
    • 6.2 错误预算
    • 6.3 端侧 SLO 的特殊性

# 01.为什么需要统一的指标体系

# 1.1 指标混乱的代价

设想以下真实对话:

  • A:我们启动优化了 30%!
  • B:你说的是冷启动还是温启动?
  • A:……都算吧,平均值。
  • B:哪一档机型?是 Time to First Frame 还是 Time to Interactive?
  • A:……

指标定义不清的结果:

  • 团队之间无法对齐 —— 同一个数字代表不同含义。
  • 优化效果不可验证 —— 改动前后的"对比"不可比。
  • 线上线下不一致 —— 实验室数据漂亮,线上灾难。
  • 老板看的报表是错的 —— 决策基于错觉。

统一指标体系的目的:让"启动 1.2s"这种描述对任何团队、任何平台都有精确、可复现、可度量的含义。

# 1.2 一个好指标的五个特征

借鉴 Google SRE 与 Brendan Gregg 的实践:

特征 含义 反例
可度量 可由仪器自动采集 "用户感觉很卡"
可定义 有数学表达,无歧义 "性能优秀"
可对比 不同时刻 / 不同版本之间可比 单次抽样
可归因 异常时能定位到具体层 "整体性能下降"
可决策 有阈值能驱动行动 "FPS 大概 50"

# 02.三种指标视角

性能指标的世界有三个互补的视角,缺一不可。

# 2.1 USE 模型 — 资源视角

由 Brendan Gregg 提出,针对任意资源的健康度三元组:

维度 含义 典型指标
Utilization 利用率 资源在被使用的时间占比 CPU% / 内存使用率 / GPU 占用率
Saturation 饱和度 排队 / 等待程度(超额需求) Run Queue 长度 / Page Fault 频率 / IO Wait
Errors 错误数 资源相关错误事件 OOM / IO Error / 网络重传

关键认知:

  • 利用率高 ≠ 有问题(CPU 100% 可能是健康的,只要不饱和、不出错)。
  • 饱和度才是性能瓶颈的真实信号。CPU 利用率 70% + Run Queue 持续 > 1,比 CPU 100% + Run Queue=0 更危险。

适用场景:CPU、内存、磁盘、网络、GPU、文件描述符、线程池…… 任何"有限资源"。

# 2.2 RED 模型 — 请求视角

由 Tom Wilkie 提出,针对任意请求型组件:

维度 含义 典型指标
Rate 速率 单位时间请求数 QPS / 启动次数 / 帧产出速率
Errors 错误率 失败请求占比 网络错误率 / 渲染丢帧率 / 崩溃率
Duration 时长 单次请求耗时分布 接口耗时 P95 / 帧时长 P99

适用场景:网络请求、页面加载、单帧渲染、单次启动、单次手势响应。

# 2.3 APDEX / Web Vitals — 用户感知视角

USE 看资源、RED 看请求,但用户不关心这些,用户关心感受。因此需要第三类指标:

# APDEX (Application Performance Index)

APDEX = (Satisfied + Tolerating/2) / Total

阈值 T 由产品定义:
  ≤ T          → Satisfied
  T < x ≤ 4T   → Tolerating
  > 4T         → Frustrated
1
2
3
4
5
6

# Google Web Vitals(Web 端事实标准,可借鉴到客户端)

指标 含义 优秀阈值 物理依据
LCP Largest Contentful Paint 主要内容渲染 < 2.5s 用户感知"加载完成"
INP Interaction to Next Paint 交互到下次绘制 < 200ms 操作反馈连续性
CLS Cumulative Layout Shift 布局抖动累积 < 0.1 视觉稳定性

# 客户端等价指标(本专栏定义)

客户端指标 Web Vitals 对应 含义
TTFM Time to First Meaningful Frame LCP 启动到首屏可见有意义内容
TTI Time to Interactive INP/TTI 启动到可响应用户操作
Tap Latency 点击响应延迟 INP 用户触摸到下一帧绘制
Frame Drop Ratio 丢帧率 — 单位时间内未按时绘制的帧占比
Jank Score 卡顿评分 — 综合卡顿严重度(次数 × 时长)

# 2.4 三视角组合使用

        用户感知(APDEX/Vitals)
              ▲
              │ "用户体验如何?"
              │
        请求时长/错误(RED)
              ▲
              │ "哪类操作出问题?"
              │
        资源饱和/错误(USE)
              ▲
              │ "为什么会出问题?"
              │
              系统层
1
2
3
4
5
6
7
8
9
10
11
12
13

自顶向下分析路径:

  1. 用户感知层(APDEX)告警 → 用户体验劣化。
  2. 下钻到 RED → 哪些请求慢 / 错?
  3. 下钻到 USE → 是哪个资源饱和 / 出错导致的?

反例:只看 USE 不看 APDEX —— "CPU 不高、内存不满,但用户骂街"。这种情况几乎一定是流水线阻塞(off-CPU stall),需要专门的方法(详见《05.归因方法论》)。

# 03.分布与百分位

# 3.1 为什么均值是性能领域的谎言

考虑两组延迟数据,单位 ms:

组 A: [50, 50, 50, 50, 50, 50, 50, 50, 50, 50]            均值 50, P99 50
组 B: [10, 10, 10, 10, 10, 10, 10, 10, 10, 410]           均值 50, P99 410
1
2

均值相同,但 B 的用户体验是灾难:每 10 次操作有 1 次卡顿 410ms。如果只看均值,你以为两个版本一样好。

为什么性能数据天然长尾?

  • GC 偶发触发
  • IO 偶发抖动
  • 缓存偶发未命中
  • 锁偶发竞争激烈
  • 网络偶发抖动

→ 性能延迟分布几乎都是右偏的、长尾的,均值被尾部样本严重拉偏。

# 3.2 百分位的物理含义

百分位 物理含义 关注场景
P50(中位数) 一半用户的体验 普遍体验
P90 10% 用户感受到的"差体验" 优化的常规目标
P95 5% 用户感受到的"明显差体验" 商业级 SLO 常用
P99 1% 用户的"灾难体验" 大流量产品必看
P99.9 / P99.99 万分之一概率的极端尾部 金融 / 关键系统

关键认知:

  • DAU 1 亿的产品,P99 = 5s 意味着每天 100 万次"灾难体验"。
  • 优化的目标不是降均值,而是压缩尾部。

# 3.3 直方图与 HDR 直方图

百分位需要从直方图计算。两种常见实现:

类型 优点 缺点 适用
等距直方图 简单 高百分位精度差 范围已知的指标
HDR Histogram 对数桶,全量程高精度 实现复杂 性能延迟(推荐)

实践要点:

  • 不要用"算 P99 = 取后 1% 平均" —— 这是错的。
  • 不要在客户端聚合 P99 后上报 —— P99 不可线性合并。
  • 上报直方图桶 + 计数,在服务端聚合后计算分位。

# 3.4 抖动与稳定性指标

均值低不代表稳定。以下指标度量"波动":

指标 含义 用途
标准差 σ 波动幅度 整体稳定性
变异系数 CV = σ/μ 相对波动 跨指标对比
P99/P50 比率 长尾扩张倍数 长尾健康度
Jitter 相邻帧 / 相邻请求时长差 帧率稳定性

帧率领域有句话:"60FPS 的均值不如 50FPS 的稳定"。用户对抖动的感知比对速度更敏感。

# 04.跨平台核心指标矩阵

下面是本专栏的"指标字典",后续章节直接引用。

# 4.1 CPU 类指标

指标 视角 定义 Android 采集 iOS 采集 Web 采集 嵌入式采集
进程 CPU 使用率 USE-U 进程占用 CPU 时间 / 总时间 /proc/[pid]/stat host_processor_info Performance API(受限) /proc/[pid]/stat
主线程 on-CPU% USE-U 主线程在 CPU 上执行时间占比 /proc/[pid]/task/[tid]/stat thread_info Long Tasks API task_struct
Run Queue 长度 USE-S 等待 CPU 的线程数 /proc/loadavg host_load_info 不可见 /proc/loadavg
上下文切换率 USE-S 每秒上下文切换次数 /proc/[pid]/status task_events_info 不可见 /proc/stat
IPC(每周期指令) 效率 单位 CPU 周期完成的指令数 simpleperf Instruments CPU Counters 不可见 perf

# 4.2 内存类指标

指标 视角 定义 Android iOS Web 嵌入式
RSS 物理内存 USE-U 实际占用物理内存 /proc/[pid]/status task_vm_info 不可见(隔离) /proc/[pid]/status
PSS 比例集 USE-U 共享内存按比例分摊后 /proc/[pid]/smaps 无对应 不可见 /proc/[pid]/smaps
Java/Heap 使用 USE-U VM 堆已用 Runtime.totalMemory() 无 performance.memory 无
GC 频率 USE-S 单位时间 GC 次数 ART trace 无(ARC) DevTools —
GC 停顿时长 USE-S 单次 GC 暂停时长 ART trace 无 PerformanceObserver(longtask) —
OOM 次数 USE-E 进程因内存被杀次数 lowmemorykiller Jetsam crash OOM Killer
内存抖动 USE-S 短时间内大量分配 / 释放 Allocation Tracker Allocations Instrument DevTools —

# 4.3 渲染类指标

指标 视角 定义
平均帧率 FPS RED-R 单位时间渲染帧数
帧时长 P99 RED-D 99% 的帧能在多长时间内绘制完成
丢帧率 RED-E 未在 Vsync 内完成的帧占比
大卡顿率 APDEX 单帧 > 700ms 的次数 / 总帧数
Jitter 抖动 相邻帧时长方差
GPU 占用 USE-U GPU 利用率
Overdraw 倍数 效率 像素被重复绘制的次数

平台采集:

  • Android:Choreographer.FrameCallback + gfxinfo + Perfetto
  • iOS:CADisplayLink + MetricKit + os_signpost
  • Web:requestAnimationFrame + PerformanceObserver(frame)
  • 嵌入式:显示控制器 IRQ + 帧缓冲交换计数

# 4.4 网络类指标

指标 视角 定义
请求成功率 RED-E 2xx + 3xx 占比
接口耗时 P95 RED-D 95% 请求完成时长
DNS / Connect / TLS / TTFB / Total 分段耗时 RED-D 请求各阶段时长
重传率 USE-S TCP 重传比例
弱网占比 环境 RTT > 阈值 / 丢包率 > 阈值的会话占比

# 4.5 启动类指标

启动是客户端最复杂的复合指标:

指标 起点 终点 物理含义
Cold Launch Time 进程创建 首帧 完整冷启动
TTFF Time to First Frame 进程创建 第一帧上屏 用户看到"动了"
TTFM Time to First Meaningful Frame 进程创建 首屏内容可见 用户看到"有用"
TTI Time to Interactive 进程创建 主线程空闲、可响应 用户能"操作"

三个时刻递进:TTFF < TTFM < TTI。多数团队只关注 TTFM,但 TTI 才决定"用户能不能用"。

# 4.6 稳定性类指标

指标 定义
Crash Rate 崩溃用户数 / DAU
ANR Rate ANR 用户数 / DAU
Foreground OOM Rate 前台 OOM 数 / DAU
异常退出率 非正常进程结束占比

# 05.指标的边界与陷阱

# 5.1 高 Goodhart's Law 风险指标

"When a measure becomes a target, it ceases to be a good measure." — Charles Goodhart

某些指标一旦被作为 KPI,团队会"针对指标"而非"针对体验"优化:

高风险指标 作弊方式
平均 FPS 把卡顿挪出采集窗口
启动时长 把耗时初始化推迟到首帧之后(伪首帧)
崩溃率 把 Crash 拦截后吞掉
内存均值 在采集时机主动 GC

对策:

  • 用多指标组合(FPS 必带 P99 + 大卡顿率)。
  • 用用户感知指标兜底(如 NPS、留存)。
  • 关键指标做采集口径文档化 + 评审。

# 5.2 平台口径差异

同名指标在不同平台口径不同,必须显式声明:

指标 Android 口径 iOS 口径 是否可直接对比
内存 PSS(含共享分摊) Footprint(不含 dirty 共享) ❌
FPS Choreographer 回调统计 CADisplayLink 回调统计 ✅(语义相近)
启动 Application.onCreate→首帧 main()→viewDidAppear ❌ 起止点不同
崩溃 包含 Native + Java + ANR 只含信号崩溃 ❌

# 5.3 采样误差与置信区间

任何指标都是样本估计,应附带置信区间:

P95 = 1.2s  ±0.05s  (95% CI, n=10000)
1

经验法则:

  • 估计 P50:样本量 ≥ 100
  • 估计 P95:样本量 ≥ 1000
  • 估计 P99:样本量 ≥ 10000
  • 估计 P99.9:样本量 ≥ 100000

样本不足时,禁止给出高百分位结论。

# 06.从指标到 SLO

# 6.1 SLI / SLO / SLA 的关系

概念 含义 例子
SLI Service Level Indicator 实际度量值 "本周冷启动 P95 = 2.1s"
SLO Service Level Objective 内部目标 "冷启动 P95 ≤ 2.0s 占比 ≥ 99%"
SLA Service Level Agreement 对外承诺 客户端通常无 SLA

# 6.2 错误预算

错误预算 = 1 - SLO

如 SLO 为 P95 ≤ 2.0s 占比 99%,
则允许 1% 的"违约时段"作为创新 / 上线的预算。
1
2
3
4

错误预算的两个用途:

  • 预算未耗尽:可激进上线、可做有风险的优化实验。
  • 预算耗尽:冻结新功能、专注治理。

# 6.3 端侧 SLO 的特殊性

服务端 SLO 主要看可用性,端侧 SLO 必须分维度切片:

切片维度 必要性
机型档位(高 / 中 / 低端) 高端机 SLO 严格,低端机宽松
系统版本 老系统给宽松目标
网络类型(WiFi / 4G / 弱网) 弱网下放宽
国家 / 地区 海外网络环境差异大
应用版本 防止新版本劣化老用户

端侧 SLO 的常见错误:用一个总均值定 SLO。结果是高端机被低端机数据掩盖、问题永远找不到。

# 07 行业 SLO 基准对照

本章汇集业界公开过的性能基准数据,作为团队制定 SLO 时的参考锚点。 数据来源:Google I/O / WWDC / 字节火山引擎 / 阿里云栖 / Meta 工程博客等公开材料。 使用注意:业界基准 ≠ 你的目标,你应该比所在行业平均高一档,比头部低一档(除非你就是头部)。

# 7.1 启动时间基准

类型 行业平均 优秀基准 头部目标 来源
Android 冷启动(中端机) 2.5-3.5s ≤ 2.0s ≤ 1.2s Google Play Console 公开
iOS 冷启动 1.5-2.5s ≤ 1.5s ≤ 0.8s WWDC 'Optimize App Launch'
Web 首屏(FCP) 2.5s ≤ 1.8s ≤ 1.0s Google Web Vitals
微信小程序冷启动 3-5s ≤ 2.0s ≤ 1.5s 微信公开课

# 7.2 渲染与卡顿基准

指标 行业平均 优秀基准 头部目标
FPS P95(60Hz) ≥ 50 ≥ 55 ≥ 58
FPS P99(60Hz) ≥ 40 ≥ 50 ≥ 55
卡顿率(帧 > 100ms) ≤ 2% ≤ 0.5% ≤ 0.1%
ANR 率 ≤ 0.4% ≤ 0.1% ≤ 0.05%
输入响应 P95 ≤ 200ms ≤ 100ms ≤ 50ms

# 7.3 内存与崩溃基准

指标 行业平均 优秀基准 头部目标
崩溃率 ≤ 0.5% ≤ 0.1% ≤ 0.02%
OOM 占崩溃比 30-50% < 20% < 10%
Java 堆峰值(中端机) 200-300MB ≤ 200MB ≤ 150MB
Native 堆 < 200MB < 150MB < 100MB

# 7.4 网络性能基准

指标 行业平均 优秀基准 头部目标
API 成功率 ≥ 98% ≥ 99.5% ≥ 99.9%
API 耗时 P95 ≤ 2s ≤ 1s ≤ 500ms
DNS 解析 P95 ≤ 200ms ≤ 100ms ≤ 50ms
弱网(地铁)成功率 ≥ 80% ≥ 95% ≥ 99%

# 7.5 头部 App 公开过的真实数字

App 场景 数字 来源
抖音 启动到首条视频可播 < 1s 字节火山引擎案例
微信 冷启动 P50 ~ 1.5s 微信公开课
手淘 冷启动到首屏 ~ 1.8s 阿里云栖大会
Instagram iOS 冷启动 < 1.2s Meta 工程博客
Notion 离线优先架构下,启动 P95 ~ 800ms Notion Engineering 博客

# 7.6 反例:失败的优化案例

案例 教训
Meta Lite 启动从 2.5s 优化到 0.8s 包体积增加 30%,发达地区收益 < 落后地区
某电商 App 全量异步化启动 启动反升 250ms(异步切换开销),后续回滚
Twitter "Predict and Preload" 实验 命中率仅 23%,整体功耗反而升高

核心启示:基准是参考,不是目标——你的业务、用户群、设备分布决定了你"应该"达到什么水平。

# 一句话总结

指标体系的价值,不是产生数字,而是产生"可决策的语言"。
当团队所有人在说"P95 帧时长"时,指的是同一件事,性能工程才能开始运转。

上次更新: 2026/06/07, 10:26:12
性能工程总论原理
性能求证方法论

← 性能工程总论原理 性能求证方法论→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式