Flutter 渲染机制

10 阅读2分钟

Flutter 渲染机制可以从三棵树、渲染流水线、更新机制、线程模型四个层面来说

三棵树结构

Flutter 使用 Widget、Element、RenderObject 三棵树实现 UI 配置与渲染的分离,从而让界面声明更简洁,同时保证渲染性能。

  • Widget 是不可变配置,只描述界面长什么样;
  • Element 负责生命周期、diff 复用;
  • RenderObject 是真正执行布局和绘制的实体。

渲染流水线

一帧画面会严格按照这几个阶段执行:

  • Build 构建

组件通过 build 方法返回 Widget 树,Flutter 会通过 Element 做 diff 对比,根据 runtimeTypekey 判断是否复用 Element,避免频繁重建。最终形成稳定的 RenderObject 树,真正负责渲染。

  • Layout 布局

遵循约束向下、尺寸向上的规则。父节点给子节点传递宽高约束,子节点计算自身大小并上报,父节点再确定子节点的位置,完成整个界面布局。

  • Paint 绘制

每个 RenderObject 执行 paint 方法,通过 Canvas 生成绘制指令,形成 Layer 树。这一步只生成指令,不直接画像素。

  • Composite 合成

引擎把多个图层按层级、透明度、变换关系合成一个画面,减少重复绘制,提升效率。

  • Raster 光栅化

由 GPU 线程把指令转为像素上屏。

脏节点更新机制

调用 setState 本质是标记当前 Element 为 dirty,加入 BuildOwner 的脏元素列表,等待下一帧统一刷新。

刷新时会通过 updateChild 做 diff。只要 runtimeType 和 key 相同,就复用 Element 与 RenderObject,只更新配置,从而避免全量重建。

线程模型

1. UI 线程(主线程)

专门负责 Flutter 渲染全流程

  • Build 组件构建
  • Layout 布局
  • Paint 绘制录制
  • Composite 图层合成

2. Raster 线程(光栅 / GPU 线程)

专门负责把绘制指令变成像素上屏

  • 执行 Skia/Impeller 光栅化
  • 调用 GPU 渲染

3. Platform 线程(原生主线程)

只负责原生层事情,不碰 Flutter 渲染

  • 原生 MethodChannel/BasicMessageChannel 回调
  • 原生 View、系统权限、相机、蓝牙、定位
  • 原生弹窗、状态栏、系统交互
  • 插件原生逻辑执行