当前位置:网站首页>Read and understand the rendering mechanism and principle of flutter's three trees
Read and understand the rendering mechanism and principle of flutter's three trees
2022-07-05 12:12:00 【CrazyCodeBoy】
Flutter Is an excellent one UI frame , With it out of the box Widgets We can build beautiful and high-performance user interfaces . Those Widgets How does it work and how does it render .
In this paper , Let's explore Widgets The story behind it -Flutter Three trees of rendering mechanism .
What are three trees ?
stay Flutter neutralization Widgets There are two other partners working together :Elements and RenderObjects; Because they all have a tree structure , So they are often called three trees .
- Widget:Widget yes Flutter The core of , Is an immutable description of the user interface . do Flutter Most of the development contacts are Widget, so to speak Widget It's up Flutter Half of the sky ;
- Element:Element Is instantiated Widget object , adopt Widget Of createElement() Method , It's used in a specific location Widget Configuration data generation ;
- RenderObject: Used for layout and drawing of application interface , Save the size of the element , Layout and other information ;
The first run of the three trees
After a preliminary understanding of the three trees , that Flutter How to create a layout ? And how the three trees work together ? Next, let's analyze their internal synergy through a simple example :
class ThreeTree extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Container(color: Colors.blue)
);
}
}
The above example is very simple , It consists of three Widget form :ThreeTree、Container、Text. So when Flutter Of runApp() What happens when a method is called ?
When runApp() When called , The following events will happen in the background for the first time :
- Flutter It will be built with these three Widget Of Widgets Trees ;
- Flutter Traverse Widget Trees , And then according to the Widget call createElement() To create the corresponding Element object , Finally, these objects are organized into Element Trees ;
- Next we'll create a third tree , This tree contains information about Widget Corresponding Element adopt createRenderObject() Created RenderObject;
The picture below is Flutter The state after these three steps :
As you can see from the diagram Flutter Created three different trees , One corresponds to Widget, One corresponds to Element, One corresponds to RenderObject. every last Element There is a corresponding Widget and RenderObject References to . so to speak Element It exists in variable Widget Trees and immutable RenderObject The bridge between trees .Element Good at comparing two Object, stay Flutter It's inside Widget and RenderObject. Its function is to configure Widget Position in the tree , And keep to the corresponding RenderObject and Widget References to .
The role of three trees
In short, it's for performance , In order to reuse Element This reduces frequent creation and destruction RenderObject. Because instantiating a RenderObject The cost is high , Frequent instantiation and destruction RenderObject It has a big impact on performance , So when Widget When the tree changes ,Flutter Use Element Trees to compare new Widget The tree and the original Widget Trees :
//framework.dart
@protected
Element updateChild(Element child, Widget newWidget, dynamic newSlot) {
if (newWidget == null) {
if (child != null)
deactivateChild(child);
return null;
}
Element newChild;
if (child != null) {
assert(() {
final int oldElementClass = Element._debugConcreteSubtype(child);
final int newWidgetClass = Widget._debugConcreteSubtype(newWidget);
hasSameSuperclass = oldElementClass == newWidgetClass;
return true;
}());
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot)
updateSlotForChild(child, newSlot);
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot)
updateSlotForChild(child, newSlot);
child.update(newWidget);
assert(child.widget == newWidget);
assert(() {
child.owner._debugElementWasRebuilt(child);
return true;
}());
newChild = child;
} else {
deactivateChild(child);
assert(child._parent == null);
newChild = inflateWidget(newWidget, newSlot);
}
} else {
newChild = inflateWidget(newWidget, newSlot);
}
assert(() {
if (child != null)
_debugRemoveGlobalKeyReservation(child);
final Key key = newWidget?.key;
if (key is GlobalKey) {
key._debugReserveFor(this, newChild);
}
return true;
}());
return newChild;
}
...
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
- If it's in a certain position Widget New Widget atypism , You need to recreate Element;
- If it's in a certain position Widget New Widget Consistent time ( Two widget Equal or runtimeType And key equal ), You just need to modify RenderObject Configuration of , There is no need to do performance-consuming analysis RenderObject The instantiation work of ;
- because Widget It's very lightweight , Instantiation costs very little performance , So it's a description APP The state of ( That is to say configuration) The best tool for ;
- A heavyweight RenderObject( It's very performance intensive to create ) You need to create as few as possible , And reuse as much as possible ;
If you see this, you will feel the whole Flutter APP It's like a RecycleView Well ?
Because in the framework ,Element It's pulled apart , So you don't have to deal with them a lot . Every Widget Of build(BuildContext context) Method context That's it BuildContext Interface Element.
Three trees at the time of renewal
because Widget It's immutable , When a Widget When your configuration changes , Whole Widget Trees need to be rebuilt . For example, when we change a Container When your color is orange , The frame will trigger a reconstruction of the whole Widget The action of the tree . Because of the Element The existence of ,Flutter It's going to be new Widget The first of the trees Widget And before Widget. Next compare Widget The second one in the tree Widget And before Widget, And so on , until Widget Tree comparison complete .
class ThreeTree extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.orange,
child: Container(color: Colors.blue,),
);
}
}
Flutter Follow a basic principle : New judgement Widget And the old Widget Is it the same type :
- If it's not the same type , Then put Widget、Element、RenderObject From their trees ( Including their subtrees ) Remove on , Then create a new object ;
- If it's a type , Then just modify RenderObject Configuration in , And then continue to traverse down ;
In our case ,ThreeTree Widget It's the same type as before , Its configuration is the same as the original one ThreeTreeRender Same , So nothing will happen . The next node is Widget In the tree is Container Widget, It's the same type as before , But its color has changed , therefore RenderObject There will be corresponding changes in the configuration of , And then it will re render , Everything else remains the same .
Pay attention to these three trees , After the configuration changes ,Element and RenderObject The instance doesn't change .
The above process is very fast , because Widget Its invariance and lightweight make it possible to quickly create , The heavyweights in the process RenderObject It's the same , Until the corresponding type of Widget from Widget Removed from the tree .
When Widget When the type of
class ThreeTree extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.orange,
child: FlatButton(
onPressed: () {},
child: Text(' skshu '),
),
);
}
}
It's the same process as before ,Flutter It will be renewed Widget The top of the tree goes down , It's different from the original tree Widget Type comparison .
because FlatButton The type and Element The corresponding position in the tree Element Different types of ,Flutter This will be removed from their respective trees Element And corresponding to ContainerRender, then Flutter Will rebuild and FlatButton Corresponding Element and RenderObject.
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-gyGvxefT-1610283167007)(https://www.devio.org/img/post/202101/flutter-three-tree-4.jpg)]
When new RenderObject After the tree is rebuilt, it will calculate the layout , And then draw it on the screen .Flutter Many optimization methods and caching strategies are used internally to deal with , So you don't have to handle this manually .
The above is Flutter The overall rendering mechanism of , It can be seen that Flutter The use of three trees is very clever to solve the problem of performance .
Reference resources
边栏推荐
- 【云原生 | Kubernetes篇】Ingress案例实战(十三)
- Hash tag usage in redis cluster
- Xi IO flow
- Open3d European clustering
- 【上采样方式-OpenCV插值】
- Tabbar configuration at the bottom of wechat applet
- Two minutes will take you to quickly master the project structure, resources, dependencies and localization of flutter
- Redis cluster (master-slave) brain crack and solution
- Uniapp + unicloud + Unipay realize wechat applet payment function
- The survey shows that traditional data security tools cannot resist blackmail software attacks in 60% of cases
猜你喜欢
pytorch-权重衰退(weight decay)和丢弃法(dropout)
Redis集群的重定向
【yolov5.yaml解析】
嵌入式软件架构设计-消息交互
Redirection of redis cluster
pytorch-多层感知机MLP
Intern position selection and simplified career development planning in Internet companies
Use and install RkNN toolkit Lite2 on itop-3568 development board NPU
redis的持久化机制原理
1个插件搞定网页中的广告
随机推荐
1个插件搞定网页中的广告
Understanding the architecture type of mobile CPU
Four operations and derivative operations of MATLAB polynomials
Redis集群(主从)脑裂及解决方案
Redis cluster (master-slave) brain crack and solution
【PyTorch预训练模型修改、增删特定层】
Matlab imoverlay function (burn binary mask into two-dimensional image)
yolov5目标检测神经网络——损失函数计算原理
【Win11 多用户同时登录远程桌面配置方法】
Pytorch linear regression
Hiengine: comparable to the local cloud native memory database engine
Select drop-down box realizes three-level linkage of provinces and cities in China
Use and install RkNN toolkit Lite2 on itop-3568 development board NPU
redis集群中hash tag 使用
谜语1
【load dataset】
Pytorch weight decay and dropout
Multi table operation - sub query
Matlab struct function (structure array)
网络五连鞭