Paint 性能
Paint 阶段负责把已经布局好的 RenderObject 绘制到 canvas。高性能绘制的核心是:只绘制需要绘制的内容,且绘制前不要做昂贵计算。
基本规则
- paint 只读布局结果,不修改布局状态。
- paint 中不要递归不可见节点。
- paint 中不要重建大型缓存。
- 文本测量应尽量在 layout 或缓存层完成。
- 可视区域外的元素应跳过。
局部绘制
DirectSurface UI 支持 dirty layer 和 transient paint。类似光标闪烁、hover 高亮、选区边缘这类变化,应尽量限制在局部 dirty rect。
如果光标闪烁导致整页重绘,需要检查:
- 光标是否调用了
markNeedsLayout。 - 光标是否让父层级整体 dirty。
- transient paint 是否能覆盖该场景。
- 是否有其他组件在同一帧请求 layout。
可视区裁剪
大列表、大文档和瀑布流必须根据可视矩形跳过不可见内容。
visible range
-> overscan range
-> layout visible items
-> paint visible items
绘制只处理可视内容,业务数据仍可保留在模型层。
搜索和选区
搜索高亮、文本选区、批注背景都应使用可视投影:
- 模型层保存全局范围。
- 绘制层只把全局范围投影到可视 render。
- 不要为了判断当前可视文本是否命中而扫描全文。
诊断方法
- 使用性能浮层看
paintMs和contentPaintMs。 - 使用 Runtime Diagnostics 看频繁 paint request 的 source。
- 对大组件增加 debugState,例如 painted row count、visible page count。
- 用浏览器 Performance 看是否 paint 前还有大量 JS 工作。