flutter uses Widgets, Elements, and RenderObjects, to deliver the 120fps eye stunning performance
Flutter layers
flutter is built on top of five layers
- Skeia Engine Low-level C++
- dart:ui
- rendering
- widgets
- Material & Cupertino
Dart:ui
provide the basic (low level) building box such as canvas, paint, textBox
but it doesn't come with all the math for calculating the layout and the hit test (Gestures)
Rendering library
handle all the heavy math works, uses caches whenever possible to reduce the computation tasks
knows what need to change within the screen
Widgets
uses Rendering library, and abstract away most of the difficulties by providing most core widgets required in any
there are three types of widgets
- Layouts such as Column Row
- Panting such as Text Image and all widgets that paint things to the screen
- Hit-Testing which is the process of listening to user actions, E.g GestureDetector
and you can compose those widgets to create more customized widgets
Material & Cupertino
a ready to use widgets compositions, that the flutter team built for covering most used elements and make the flutter developer life easier
the Widgets/Elements/Render trees
when runApp executed flutter start by
- create a widgets three the configurations tree
- flutter walk down the widgets three and call the createElement() in every widget thereby creating an Elements tree
- flutter walk down again the widgets three and call the createRenderObject() in every widget thereby creating a RenderObjects tree
whats RenderObjects?
knows how to paint a widget by applying expensive computations
it takes care of layout, painting, hit-testing (user gestures)
it's crucial to use RenderObjects very carefully because they are very expensive to instantiate, and because widgets often change and they very perceptible to deletion, we need a better way to link the chip (widgets) and the expensive (RenderObjects) together in an efficient manner
introducing, Elements!
Elements are the magic Glue that insure the lightness of widgets(immutable) and the hardness of RenderObjects(mutable)
Elements are principally objects that are good at comparing two objects with each other, in our case the widget and the render object. They represent the use of a widget to configure a specific location in the tree and keep a reference to the related Widget and RenderObject.
Why having three trees
each time a change happens to the widgets tree, flutter uses the element tree to compare the new widget tree with the existing RenderObject tree
if the widget type didn't change flutter updates only the mutable proprieties of the correspondence widget RenderObject, and thus, it saved us from recreating the expensive RenderObject.
but if the type did change flutter remove the old RenderObject
whoever, it's very unlikely to use directly those Element,
The BuildContext passed in every build(BuildContext context) function is the corresponding Element wrapped into the BuildContext interface and that’s why it’s different for every single widget.
Computing the Next Frame
since widgets are immutable, anytime a widget configurations changes, flutter will rebuild the entire subtree (its root is the changed widget)
with the help of the Element tree, flutter compares the first new widget with the first old render in the tree, then the second widget with the second render ...
the comparison consist of checking the type of the new widget three with what was previously created in the Element tree
- whenever the new widget (type or key) doesn't match the old one flutter removes the old widget (including its sub-tree) and it also removes the correspondent Element, renderObject
- when the type and key didn't change, flutter still uses the Element (that holds the state of the widget) and applies any state change to the renderObject by changing its configurations (because renderObject is mutable).