尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Perfetto 实战:用帧时间线数据分析 Gmail 滚动卡顿——统计 Jank 帧、归因 Jank 类型并定位最差帧

Perfetto 实战:用帧时间线数据分析 Gmail 滚动卡顿——统计 Jank 帧、归因 Jank 类型并定位最差帧 Perfetto 实战用帧时间线数据分析 Gmail 滚动卡顿——统计 Jank 帧、归因 Jank 类型并定位最差帧【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto导读本文以 ai/evals/cases/jank-worst-frame/prompt.md 这个真实评测用例为线索完整演示一条 Android 卡顿jank分析链路拿到一份复现了 Gmail 会话列表滚动卡顿的 Perfetto tracejank.pftrace后如何回答三个层层递进的问题——Gmail 共有多少帧是 janky 的、trace 把这些卡顿归因于哪些 jank 类型、以及其中最差的一帧是哪一帧。文中会给出可复现的trace_processor_shellSQL 查询、参考答案ground truth并结合 android_frame_timeline_metric.sql 等源码剖析帧时间线表与 jank 分类的底层原理最后说明这个用例在 Perfetto AI Agent 评测体系中扮演的角色。读完你将掌握一套从原始 trace到卡顿归因结论的完整分析方法并理解 jank 类型如 Buffer Stuffing、App Deadline Missed的真实语义。案例背景一份复现了卡顿的 Gmail trace用例的原始描述摘自 prompt.md是Users say the Gmail conversation list stutters while scrolling. I captured ./jank.pftrace with Perfetto while reproducing it. How many of Gmails frames were janky, what kinds of jank does the trace attribute them to, and which single frame was the worst?翻译过来即用户在滚动 Gmail 会话列表时遇到卡顿复现时用 Perfetto 抓取了jank.pftrace。需要回答三个问题数量Gmail 的帧中有多少帧是 janky卡顿的类型trace 将这些卡顿分别归因于哪些 jank 类型例如 Buffer Stuffing、App Deadline Missed最差帧最差的那一帧是哪一帧帧 token、时长、jank 类型、归属 layer这个案例被刻意设计为hard难度frontmatter 中tags: [android, jank, frames, hard, stdlib]它要求多步分析而错误的方法会得出看似合理的错误数字——例如把非 Gmail 进程的帧也算进去、或把 expected期望帧时间线与 actual实际帧时间线混淆都会得到错误的统计结果。它同时被标记为stdlib意味着 Perfetto 标准库trace processor 内置的 SQL 模块足以支撑绝大多数分析工作。数据准备从原始 trace 到可查询的帧时间线用例 frontmatter 声明了 trace 的来源与落地文件名files: - src: {repo}/test/data/webview_jank.pb dst: jank.pftrace即仓库的测试数据test/data/webview_jank.pb会被复制为工作区中的jank.pftrace。这类 trace 属于 WebView/Android 帧相关数据仓库中对应的回归测试位于 test/trace_processor/diff_tests/metrics/webview/tests.py 与 test/trace_processor/diff_tests/parser/graphics/tests.py。分析入口是trace_processor_shell构建说明见 ai/skills/perfetto/environment-references/setup.md# 启动交互式 shell 并加载 trace trace_processor_shell jank.pftrace # 或直接以 --query 执行单条 SQL trace_processor_shell --query SELECT ... jank.pftrace加载后Android 的 FrameTimeline 数据会被解析成若干标准表本案例的核心是actual_frame_timeline_slice实际帧时间线切片。该表每行描述一帧实际发生的情况关键列包括display_frame_token显示帧的唯一 token用于跨表关联和精确定位某一帧process_name/upid提交该帧的进程本案例中为com.google.android.gm即 Gmaillayer_name渲染该帧的 layer本案例最差帧属于ConversationListActivityGmail即会话列表 Activitydur帧实际耗时纳秒是判定卡顿与排序的核心指标jank_typetrace 对该帧卡顿的归因类型字符串可能为空表示该帧不卡顿present_type呈现方式标记如Late Present迟到呈现。重要前提FrameTimeline 表只存在于包含 Android FrameTimeline 事件SurfaceFlinger帧时序的 trace 中因此本分析方法适用于 Android 12 上录制、且抓取了帧时间线数据的 trace普通 ftrace 或纯 CPU trace 中没有这些表。问题一统计 janky 帧数量帧是否卡顿直接体现在jank_type是否为空。空表示该帧按时完成非空表示被判定为某种卡顿。一个可靠的统计查询如下SELECT COUNT(*) AS total_frames, COUNT(*) FILTER(WHERE jank_type ! ) AS janky_frames, COUNT(*) FILTER(WHERE jank_type ) AS smooth_frames FROM actual_frame_timeline_slice WHERE process_name com.google.android.gm;注意两个关键过滤条件缺一不可必须限定process_name com.google.android.gmtrace 中同时存在 SurfaceFlinger、SystemUI、其他应用等多进程的帧不限定进程会把无关帧计入必须使用actual_frame_timeline_slice而非expected_frame_timeline_sliceexpected 表描述预期何时呈现actual 表描述实际何时呈现卡顿判定deadline 是否错过发生在 actual 侧。参考答案ground truth该用例的 ground truth 记录在 graders/janky-count.mdGround truth (actual_frame_timeline_slice for com.google.android.gm): 116 frames, 43 janky: 31 Buffer Stuffing, 9 App Deadline Missed, 3 both.即 Gmail 共有116 帧其中43 帧 janky约 37%。grader 的校验正则接受 4045 之间的计数变体说明这类统计对边界情形如是否计入最后一帧、是否剔除异常 token存在合理容差回答时给出数字的同时说明统计口径更有说服力。问题二jank 类型归因——Buffer Stuffing 与 App Deadline Missed得到 janky 帧数后第二步是按类型拆解SELECT jank_type, COUNT(*) AS n FROM actual_frame_timeline_slice WHERE process_name com.google.android.gm AND jank_type ! GROUP BY jank_type ORDER BY n DESC;一个帧的jank_type可能是多个类型的逗号拼接例如同时命中两种归因因此更严谨的写法是先把类型按逗号拆分再统计。参考答案为Buffer Stuffing缓冲填塞31 帧—— 主导类型grader 要求必须点出App Deadline Missed应用错过截止时间9 帧两者兼具3 帧。graders/jank-types.md 明确指出Buffer Stuffing is the dominant jank type (31 of 43) and must be named; App Deadline Missed is the other.源码视角jank 类型如何被归因与分类jank_type字符串并非 SQL 层凭空生成的而是来自 Android FrameTimeline 的原始事件数据trace processor 的指标模块在此基础上进一步做分类聚合。android_frame_timeline_metric.sql 展示了这一层的处理逻辑用递归 CTEsplitted_jank_type_timeline见 android_frame_timeline_metric.sql把逗号拼接的jank_type拆成单条记录便于逐类型统计通过GLOB匹配把细粒度类型归纳为宏观类别jank_type GLOB *App Deadline Missed* OR jank_type GLOB *App Resynced Jitter* AS missed_app_frame, jank_type GLOB *SurfaceFlinger CPU Deadline Missed* OR jank_type GLOB *SurfaceFlinger GPU Deadline Missed* OR jank_type GLOB *SurfaceFlinger Scheduling* OR jank_type GLOB *Prediction Error* OR jank_type GLOB *Display HAL* AS missed_sf_frame,见 android_frame_timeline_metric.sql这揭示了两类归因的语义边界App Deadline Missed应用侧提交帧太晚错过了 deadline属于missed_app_frame一类通常与主线程/渲染线程超时、丢帧、输入响应慢有关Buffer Stuffing属于呈现流水线侧的缓冲行为问题——SurfaceFlinger 侧积累了过多的待呈现 buffer填塞导致显示的帧落后于最新内容。注意它不归入上述missed_*分类splitted_jank_type_timeline的missed_frame判断只覆盖 deadline/drop 类因此单独识别它、并把它作为主导卡顿类型报告正是本用例考核的核心点之一。由此可以推断Gmail 案例中约 72%31/43的卡顿帧是缓冲流水线侧的填塞问题只有约 21%9/43是应用错过 deadline——这是一个瓶颈在呈现队列而非应用主线程的典型信号分析时不应只盯 App 侧代码。android_jank_cuj系列模块src/trace_processor/metrics/sql/android/jank/进一步把帧关联到 CUJ关键用户旅程可作深入参考。问题三定位最差的那一帧最后一步是按耗时降序找出最差帧SELECT display_frame_token, dur / 1e6 AS dur_ms, jank_type, present_type, layer_name FROM actual_frame_timeline_slice WHERE process_name com.google.android.gm ORDER BY dur DESC LIMIT 1;参考答案ground truthgraders/worst-frame.md 给出的最差帧为Worst frame: display_frame_token 614218, 497.9 ms, App Deadline Missed, Late Present, layer ConversationListActivityGmail.即display_frame_token614218耗时约 497.9 ms约等于 30 帧的时长属于肉眼可见的卡死一下级别jank 类型App Deadline Missed呈现方式Late Present迟到呈现归属 layerConversationListActivityGmail即用户反馈卡顿的会话列表界面497.9 ms 的帧意味着应用在该帧上严重超时deadline 早已错过最终只能迟到呈现。与之对比Buffer Stuffing 类帧的耗时通常不如这类极端这也说明类型归因与最差帧是两个不同维度的问题数量上 Buffer Stuffing 主导但严重性上 App Deadline Missed 的这帧最极端——回答时必须分别作答不能混为一谈。评测视角这个用例如何被用于衡量 AI Agent理解了问题与答案后再看它在 ai/evals/README.md 描述的评测体系中如何运作能帮助理解ground truth 从哪来、为什么这样设计runs: 3每个条件condition下该用例会运行 3 次因为非确定性的 Agent 单次运行只是噪声分级器graders设计遵循先确定性后 LLMjanky-count.md、jank-types.md、worst-frame.md都是 regex grader用正则匹配答案中的数字与关键词如\b4[0-5]\b匹配 4045 的帧数可复现、不可被说服而 grounded.md 是llm分级器只用来判定结论是否 grounded有 trace 数据支撑、没有编造例如允许数字有约 10% 容差但没有帧数、没有 jank 类型、或最差帧时长不同则判定失败ground truth 本身来自trace_processor每个 grader 体内记录的是产生期望值的查询口径actual_frame_timeline_sliceforcom.google.android.gm保证参考答案不是拍脑袋为什么这个用例能失败README 指出评测集刻意包含错误方法会得到看似合理的错误数字的多步题hard标签。本案例中若 Agent 不限定进程、误用 expected 表、或把多类型拼接的帧重复计数都会得到一个貌似合理但错误的答案——这正是它作为评测用例的价值所在。运行该用例的入口示例详见 ai/evals/README.mdai/evals/run_evals.py run --conditions baseline-tp,skill-local --runs 3 --jobs 5方法总结与可复现要点问题核心查询对象关键过滤条件参考答案多少帧 jankyactual_frame_timeline_sliceprocess_name com.google.android.gm且jank_type ! 116 帧中 43 帧 janky哪些 jank 类型同上按jank_type分组注意逗号拼接限定 Gmail 进程Buffer Stuffing 31、App Deadline Missed 9、两者兼具 3最差的一帧同上按dur降序限定 Gmail 进程token 614218、497.9 ms、App Deadline Missed、Late Present、layer ConversationListActivityGmail复盘要点先框定进程再谈帧统计——多进程 trace 中漏掉进程过滤是头号错误来源区分 actual 与 expected 帧时间线——卡顿判定在 actual 侧jank 类型是多值拼接——需要拆分统计且数量主导类型与最严重帧类型可能不同本案例前者是 Buffer Stuffing后者是 App Deadline Missedground truth 可复现——上述 SQL 均可在 graders 目录找到口径依据源码分类逻辑见 android_frame_timeline_metric.sql。这套方法同样适用于任何含 FrameTimeline 数据的 Android 卡顿排查统计卡顿比例 → 按 jank 类型归因定位瓶颈层应用侧 / SurfaceFlinger 侧→ 钻取最差帧的 token 与 layer从而把用户说卡转化为可量化、可归因、可定位的具体结论。【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表