Flutter, the marvelous of 120 fps

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

  1. create a widgets three the configurations tree
  2. flutter walk down the widgets three and call the createElement() in every widget thereby creating an Elements tree
  3. 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).