渲染管线
DirectSurface UI 的运行时管线由事件、状态变更、layout、paint、composite 几个阶段组成。性能排查时要先判断卡顿发生在哪个阶段,而不是直接猜测某个组件慢。
核心对象
RuntimeHost:管理 canvas、事件、调度、图层和诊断。FrameScheduler:合并一帧内的重绘请求。PipelineOwner:管理 dirty layout、dirty paint 和 render tree。- 图层管理器:管理主图层、overlay、debug overlay、performance overlay。
Compositor:把 dirty layer 绘制到 canvas。
请求类型
运行时诊断中 paint request 分为:
frame:只需要新帧绘制。layout:需要先布局,再绘制。
来源分为:
pipelineoverlayruntimewindowdebug
排查频繁重绘时,优先看 request 的 kind、source、reason 和调用栈。
正常流程
Pointer / Keyboard / Timer / State Change
-> markNeedsLayout / markNeedsPaint
-> RuntimeHost scheduleLayout / scheduleFrame
-> FrameScheduler 合并到下一帧
-> PipelineOwner flushLayout
-> PipelineOwner flushPaint
-> Compositor paint dirty layers
同一帧内多次请求应被合并。如果同一个组件每帧都请求 layout,需要检查 setter、layout 阶段和外部同步逻辑。
性能浮层
性能浮层记录最近帧数据:
totalMslayoutMspaintMscontentPaintMstransientPaintMscompositeMslayoutNeededrootCountlayerCount
如果 paintMs 很低但用户仍感觉卡顿,要继续看事件处理、输入 composer、浏览器主线程任务和布局前的数据更新。
使用建议
- hover、光标闪烁、tooltip 移动通常只应触发 paint,不应触发 layout。
- 输入时如果当前段落高度不变,应尽量走局部 patch。
- layout 中不要写入每帧都变化的新数组或对象,除非值确实变化。
- paint 中不要做全量数据转换、文本测量缓存重建或业务查询。