重组性能分析工具

大约 5 分钟

重组性能分析工具

本页说明如何使用 Kuikly Compose 内建的 RecompositionProfiler 工具,在调试阶段定位重组性能问题。

主要能力:

  • 自动追踪所有 Composable 的重组次数与耗时(无需修改业务代码)
  • 精确显示触发重组的 State 对象及其值变化(prev → now
  • 检测参数级变更(哪个参数导致了本次重组)
  • 悬浮热点面板(Overlay),实时可视化重组热点
  • 自动写文件(JSON 报告 + 逐帧数据),供 AI 离线分析
  • 多平台一致:iOS、Android、HarmonyOS 行为相同

快速开始

1. 启动 Profiler

// 配置(可选,不调用则使用默认配置)
RecompositionProfiler.configure {
    sampleRate = 1.0f          // 采样率,1.0 = 全量采集
    hotspotThreshold = 10      // 热点阈值
    enableLog = true           // 默认 true,开启日志输出
    enableFile = true          // 默认 true,开启文件写入,供 AI 离线分析
    enableOverlay = true       // 启用悬浮热点面板(默认 false)
}

// 启动
RecompositionProfiler.start()

默认行为start() 后自动开启日志输出(enableLog = true)和文件写入(enableFile = true),文件写入用于 AI 离线分析重组问题,无需手动配置。

2. 获取报告

// 获取结构化报告(Profiler 运行中或 stop 后均可调用)
// saveToFile=true(默认)会同时将报告写入 profiler_report.json
val report = RecompositionProfiler.getReport()

// 输出 JSON
println(report.toJson())

3. 停止 Profiler

RecompositionProfiler.stop()
// stop 后自动写 profiler_report.json,仍可调用 getReport() 获取数据

4. 重置数据

RecompositionProfiler.reset()

清空当前会话内所有已采集的重组数据(帧事件、组件统计、State 变更记录),计数从零重新开始。适合在切换测试场景时使用,Profiler 保持运行状态不中断。


输出格式

日志格式

日志 Tag 为 RCProfiler,每行单独输出,可用此 Tag 过滤所有重组日志:

# Android
adb logcat -s "RCProfiler"

# iOS 控制台(console.log)
grep "RCProfiler" logs/kuikly_console.log

# HarmonyOS
grep "RCProfiler" logs/kuikly_ohos.log

每帧只要发生重组就输出一个 Frame 块(无重组的帧不输出),每行独立带 Tag:

[RCProfiler] Frame #42 START (ts=1774431764564ms)
[RCProfiler]   RECOMPOSED: CounterSection @RecompositionProfilerDemoPage.kt:221 (1ms) [parent=<unknown>] params=[no params change] triggers=[State(prev=1, now=2), readers: CounterSection]
[RCProfiler]   RECOMPOSED: LambdaChild @RecompositionProfilerDemoPage.kt:331 (0ms) [parent=ParentChildDemo] params changed: [#1] (1/2) triggers=[]
[RCProfiler] Frame #42 END (duration=5ms, recomposed=2)

字段说明:

字段说明
Frame #N帧序号,从 1 开始累计递增(包含无重组的帧),相邻输出的帧号可能不连续,属正常现象
@File.kt:LineComposable 函数的源码声明位置(编译器限制,不是调用位置)
(Xms)本次重组耗时
params=[no params change]参数未变化,重组由 State 变化触发
params changed: [#1]第 1 号参数发生变化(父组件传入新值)
triggers=[State(prev=1, now=2)]触发此次重组的 State 及值变化
readers: CounterSection读取该 State 的组件名

Overlay 热点面板

启用 enableOverlay = true 后,页面右下角出现悬浮圆形按钮,可拖动位置:

Overlay FABOverlay 展开面板
悬浮 FAB展开热点面板
  • 正常态:显示当前会话累计重组次数,绿色(无重组)→ 橙色 → 红色(高频重组)
  • 暂停态:显示 ||,数据更新暂停但 Overlay 仍可见
  • 点击展开:居中面板展示热点列表

热点面板功能

按钮功能
暂停 / 继续暂停或恢复 Overlay 数据更新(不影响底层采集,也不隐藏面板)
重置清空所有计数,等同于 RecompositionProfiler.reset()
报告将完整 JSON 报告输出到控制台日志

热点列表说明

  • 函数名聚合,同名组件的所有实例合并统计
  • 包含首次组合和重组,按总次数降序排列
  • 每条显示:组件名(左)、累计次数(右)、源码声明位置(第二行灰色小字)
  • 最多展示 overlayTopCount 条(默认 10)

为什么不按实例区分:Compose Runtime 的 traceEventStart key 是函数维度(非调用点),不同驱动方式(State 失效 vs 参数驱动)下实例 key 的可用性不一致,强行区分会导致部分组件有序号、部分没有,行为不统一。实例级细节可通过日志的 RECOMPOSED 输出(含 parent 信息)查看。


配置项说明

配置项类型默认值说明
sampleRateFloat1.0采样率(0.0~1.0)。0.5 表示约 50% 的帧被记录,可降低性能开销
hotspotThresholdInt10热点判定阈值:Report 中 isHotspot = true 的判定条件
maxEventBufferSizeInt10000事件缓冲区最大容量,超出时丢弃最旧事件
includeFrameworkComposablesBooleanfalse是否包含框架内部 Composable(Row/Column 等)。默认只监控业务代码
enableLogBooleantrue是否开启日志输出。仅在 start/stop 期间有效
enableFileBooleantrue是否开启文件写入,供 AI 离线分析。仅在 start/stop 期间有效
enableOverlayBooleanfalse启用悬浮热点面板。需在 start() 前设置
overlayTopCountInt10热点面板展示的最大条目数

注意事项

  • 性能:Profiler OFF 时零开销(编译器注入的 trace 调用被短路)。建议只在开发/测试包中启用,不要在生产包中 start()
  • 数据范围RecompositionProfiler 是全局单例,start() 后所有页面的重组都会被采集,多页面跳转时数据累积在一起。如需按页面分析,建议在进入目标页面时 reset()
  • Overlay 开关enableOverlay 需要在 start() 之前通过 configure { } 设置。
  • 采样率:高频重组场景(如 60fps 动画)可设置 sampleRate = 0.3 降低日志量。
  • 文件位置:写入 App 沙盒目录(iOS/Android 写 Caches,HarmonyOS 写 files),系统磁盘紧张时 Caches 可能被清理;分析完建议及时备份。