Flutter布局和渲染流程
图像显示原理
- CPU负责
图像数据计算, 然后交给 GPU - GPU负责
图像数据渲染, 渲染后放入帧缓冲区 - 视频控制器根据
垂直同步信号(VSync)以每秒60次的速度,从帧缓冲区读取帧数据交由显示器完成图像显示。
Flutter 图像显示流程

UI线程使用Dart来构建视图结构数据(Widget),这些数据会在GPU线程进行图层合成,随后交给Skia引擎加工成GPU数据,- GPU数据通过OpenGL最终提供给GPU渲染。
- 需要在两个
VSync信号之间完成这些操作,不然会卡顿
Skia是什么?
-
Skia是一款C++开发的、跨平台、性能优秀的2D图像绘制引擎
-
Skia是
Android官方的图像渲染引擎,所以无需内嵌Skia引擎就可以获得天然的Skia支持; -
iOS: 嵌入到Flutter的 iOS SDK中,替代了iOS闭源的Core Graphics/Core Animation/Core Text,这也正是 iOS App包体积比Android要大一些的原因。 -
Skia 优点
Skia统一了各个系统的渲染逻辑, 保证同一套代码在Android和iOS平台上的渲染效果是完全一致的。
Flutter界面渲染过程
- 页面中的Widget以树的形式组织成
控件树。 - 为控件树中的每个Widget创建不同类型的
渲染对象(RenderObject),组成渲染对象树。 - 渲染对象树展示过程分为四个阶段:
布局、绘制、合成和渲染。
布局
- Flutter采用
深度优先遍历渲染对象树,决定渲染对象树中各渲染对象在屏幕上的位置和尺寸。 - 渲染对象树中的每个渲染对象都会接收父对象的布局约束参数,决定自己的大小,
- 父对象按照控件逻辑决定各个子对象的位置,完成布局过程。

Flutter在某些节点设置布局边界(Relayout Boundary),当边界内的任何对象发生重新布局时,不会影响边界外的对象。

绘制
- 把渲染对象绘制到不同的
图层上。 - 绘制过程也是
深度优先遍历,先绘制自身,再绘制子节点。
以下图为例:节点1在绘制完自身后,会再绘制节点2,然后绘制它的子节点3、4和5,最后绘制节点6。
子节点5与它的兄弟节点6处于了同一层,当节点2重绘的时候,与其无关的节点6也会被重绘,带来性能损耗。
为了解决这一问题,Flutter使用重绘边界(Repaint Boundary), Flutter强制切换新的图层,避免无关内容置于同一图层引起不必要的重绘。

Scrollview使用重绘边界, 保证滚动时只重绘可视内容,不可见内容不重绘。
合成
- Flutter的渲染树层级很多,直接交付给渲染引擎进行
多图层渲染,会出现大量渲染内容的重复绘制, - 图层合成: 将所有的图层根据大小、层级、透明度等规则计算出最终的显示效果,将相同的图层归类合并,简化渲染树,提高渲染效率。
渲染
合成完成后,Flutter将几何图层数据交由Skia引擎加工成二维图像数据,最终交由GPU进行渲染,完成界面的展示。
转载自:https://juejin.cn/post/7242815848087486520