You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose 如何统计UI渲染耗时?

Jetpack Compose 场景下Fragment UI渲染耗时统计方案

核心逻辑是分别记录渲染触发起点和UI完成渲染终点两个时间戳,差值就是总渲染耗时,以下是可直接落地的实现方案:

1. 确定统计起点

通常选Fragment触发Compose加载的时机作为起点,直接在Fragment的onCreateView生命周期中记录时间戳即可:

class YourFeatureFragment : Fragment() {
    // 存储渲染开始时间戳
    private var renderStartTime = 0L

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        renderStartTime = System.currentTimeMillis()
        return ComposeView(requireContext()).apply {
            setContent {
                YourFeatureScreen()
            }
        }
    }
}

2. 统计纯UI渲染耗时(无异步数据依赖场景)

如果页面不需要等待接口返回、静态UI渲染完成就算结束,可以用Compose提供的onGloballyPositioned修饰符,它会在布局计算完成、位置确定时回调,刚好对应UI首次渲染完成的时机:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    renderStartTime = System.currentTimeMillis()
    return ComposeView(requireContext()).apply {
        setContent {
            // 标记是否已经上报,避免后续布局变更重复触发统计
            val hasReported = remember { mutableStateOf(false) }
            // 修饰符加在整个页面的根Composable上
            YourFeatureScreen(
                modifier = Modifier.onGloballyPositioned {
                    if (!hasReported.value) {
                        val renderCost = System.currentTimeMillis() - renderStartTime
                        // 此处可替换为你自己的埋点上报逻辑
                        Log.d("RenderTrack", "静态UI渲染总耗时:${renderCost}ms")
                        hasReported.value = true
                    }
                }
            )
        }
    }
}

3. 统计完整首屏渲染耗时(含异步数据依赖场景)

如果页面需要等接口返回数据、列表渲染完成才算首屏结束,可以结合业务状态判断,等数据加载完成后再触发统计:

该方案可以精准对齐业务侧的首屏定义,不会把骨架屏、加载态的渲染时间当成最终首屏耗时

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    renderStartTime = System.currentTimeMillis()
    return ComposeView(requireContext()).apply {
        setContent {
            val viewModel: YourFeatureViewModel = viewModel()
            // 监听页面业务状态
            val pageState by viewModel.pageState.collectAsStateWithLifecycle()
            val hasReported = remember { mutableStateOf(false) }

            when(pageState) {
                is PageState.Loading -> LoadingSkeleton()
                is PageState.Error -> ErrorPage()
                is PageState.Success -> {
                    // 数据加载成功后渲染内容页,再监听布局完成回调
                    FeatureSuccessPage(
                        data = (pageState as PageState.Success).data,
                        modifier = Modifier.onGloballyPositioned {
                            if (!hasReported.value) {
                                val renderCost = System.currentTimeMillis() - renderStartTime
                                Log.d("RenderTrack", "完整首屏渲染总耗时:${renderCost}ms")
                                hasReported.value = true
                            }
                        }
                    )
                }
            }
        }
    }
}

4. 无侵入式系统级统计方案

如果不想侵入Compose业务代码,可以给ComposeView设置绘制监听,首次绘制完成就是渲染结束时机:

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    renderStartTime = System.currentTimeMillis()
    return ComposeView(requireContext()).apply {
        setContent {
            YourFeatureScreen()
        }
        viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                val renderCost = System.currentTimeMillis() - renderStartTime
                Log.d("RenderTrack", "首次绘制完成耗时:${renderCost}ms")
                // 用完就移除监听,避免重复触发
                viewTreeObserver.removeOnPreDrawListener(this)
                return true
            }
        })
    }
}

两种方案的适用场景:

  • onGloballyPositioned方案:适合需要自定义首屏结束节点、对齐业务统计标准的场景,灵活性更高
  • OnPreDrawListener方案:适合不需要区分业务加载状态、只需要统计系统层面首次绘制耗时的场景,不需要修改业务Composable代码

内容的提问来源于stack exchange,提问作者Sandesh Baliga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 01:03:00