当前位置:网站首页>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
边栏推荐
- Redis集群的重定向
- [pytorch pre training model modification, addition and deletion of specific layers]
- redis的持久化机制原理
- 【 YOLOv3中Loss部分计算】
- Design of music box based on assembly language
- Pytorch MLP
- Reinforcement learning - learning notes 3 | strategic learning
- Image hyperspectral experiment: srcnn/fsrcnn
- Linux Installation and deployment lamp (apache+mysql+php)
- Network five whip
猜你喜欢
什么是数字化存在?数字化转型要先从数字化存在开始
How to clear floating?
【TFLite, ONNX, CoreML, TensorRT Export】
Multi table operation - Auto Association query
【Win11 多用户同时登录远程桌面配置方法】
简单解决redis cluster中从节点读取不了数据(error) MOVED
多表操作-自关联查询
redis主从中的Master自动选举之Sentinel哨兵机制
Embedded software architecture design - message interaction
Check the debug port information in rancher and do idea remote JVM debug
随机推荐
Xi IO flow
pytorch-权重衰退(weight decay)和丢弃法(dropout)
调查显示传统数据安全工具在60%情况下无法抵御勒索软件攻击
ACID事务理论
codeforces每日5题(均1700)-第五天
强化学习-学习笔记3 | 策略学习
July Huaqing learning-1
HiEngine:可媲美本地的云原生内存数据库引擎
Pytorch softmax regression
【TFLite, ONNX, CoreML, TensorRT Export】
Want to ask, how to choose a securities firm? Is it safe to open an account online?
redis集群中hash tag 使用
Video networkstate property
MySQL splits strings for conditional queries
Codeworks 5 questions per day (1700 average) - day 5
Codeforces Round #804 (Div. 2)
II. Data type
Four operations and derivative operations of MATLAB polynomials
What is the difference between canvas and SVG?
自动化测试生命周期