I've been working with Flutter for Web for quite some time now and it is amazing, which made me curious about how it exactly functions. So I decided to take a look under the hood and see what I can find. In this article, I will take you on the journey that shows you how Flutter Web works.
The old days of development where we used to write different sets of code for different platforms for a single product are gone. With Flutter, we only need to write a single set of code for the same product and it can run on different platforms.
Before diving deep into how Flutter for Web works, its layout its widgets and how it paints all those widgets on the screen, let's have a basic understanding of how a browser's rendering engine works because it's a very fundamental concept required in relating the Flutter Web engine with the browser.
You can divide a Browser's Architecture mainly into three parts:
- User Interface: Everything that is visible to the user on the web page.
- Browser Engine: It acts like a bridge between User Interface and the Rendering Engine and serves resources to the Rendering Engine.
- Rendering Engine: It's job is to compile all those HTML, CSS, JS etc. files, generate layouts and paint them on the screen.
Stages of compilation and painting on screen:
- Loading of Web Page:
The moment you hit a particular URL your browser loads a HTML page, It is in the form of binary streams.
This binary file contains
- Critical Rendering Path:
Now our browser has all the required files which it can render on the web page and it gives these files to the Rendering Engine, which starts generating a layout through these files and painting them on the screen.
Critical Rendering Path:
- DOM Construction:
Your browser goes through HTML page and starts extracting the HTML nodes and then create the DOM tree through it.
- CSSOM Construction:
In the same fashion, your browser goes through the page and starts extracting the CSS properties from it and create a CSSOM tree through it.
- Render Tree Construction:
This is the combination of both DOM tree and CSSOM tree and it contains the lower level representation of the whole content that is going to be visible on the web page.
- Layout Operation:
When the browser is done with the creation of all the trees, it performs a layout operation and starts calculating the position coordinates and all mathematical operations that are required to calculate the layout of the views.
- Paint Operation:
Finally, when the browser has those layers calculated, it performs refining and rasterisation, and paints them on the screen. But sometimes this process executes in two parts, Paint and Composition.
This whole process from creation of render tree to calculation of Layouts and finally painting is known as Critical Rendering Path and we can relate this browser working to the the working of Flutter Web.
So, let's jump in to Flutter.
Flutter is made up of two high level components:
- Flutter FrameWork:
It contains Libraries, Widgets, Material, Cupertino Library, Gestures, Animation etc.
- Flutter Engine:
This part is totally independent of the Framework layer and contains Dart VM, Service Protocols, Platform Channels and many more.
This is how Flutter Architecture and Flutter Web Architecture both differ from each other:
All those Components that make the Framework Layer are also present in the Framework Layer of Flutter Web from Material Library to Gestures, Animation and Widgets.
If we talk about the Engine Layer, everything that is present inside it is also present inside the Flutter Web Engine from Dart VM to Rendering, System Events and Platform Channels.
Then what's the difference?
The difference lies in the Engine layer and how it is implemented as it contains some libraries and APIs which help in conversion of dart code into html, css and js code.
Let's figure it out.
Till now, we know the browser does not understand any dart code. That's why the Flutter Web Engine requires different set of tools to render its content on browser.
Flutter Web Architecture:
This is how the Flutter Web Architecture looks like in more detail. We have Flutter Web Engine which contains some libraries and APIs to convert the Dart code into HTML, CSS, as well as the dart2js compiler for the conversion of Dart code into JS code.
Let's look into how does this process takes place step by step:
- First, your code written in Dart goes through the Flutter Web Engine and then compiles to HTML and CSS.
- In the end, the required files are served to the browser.
Why The Extra Layer?
Why have dart2js compiler as extra layer.
Here is what the Wikipedia page has to say about this:
It says that the Dart can run faster than an equivalent hand-written code in most of the cases. The Dart FAQ page says that they are also working on making common cases run faster.
Right now, we have our Dart code compiled into HTML, CSS and JS. Now let's see how the painting operation is taking place:
Each and every time Flutter renders a UI, it creates widgets, layouts and then finally paints them on the screen. This is what the whole process looks like as a big picture:
- Widgets: In the first step, widgets get created. This operation is done by the framework and is totally independent of Flutter Web engine and browser rendering engine.
- Layouts: In this step, a layout operation is performed on all the widgets that are created which calculate the position, size, height and width etc..
- Painting: In the last step, the widgets wrapped with layers that can be expressed are wrapped in the HTML and CSS and those which cannot are wrapped inside Canvas element.
This whole process is known as DOM Canvas implementation.
In the below picture you can see the DOM Canvas tree which you can find in chrome inspector:
Why so Many Nodes ?
But now the question arises, why are we seeing so many nested nodes there?
The answer lies in the painting operation and the creation of Render Tree.
At the time of performing the painting operation, Flutter creates a render Tree and the render tree creates Composite Layers which is supplied to the Flutter Engine. This Composite Layer contains information like Offset, Transform, Scene and many more and as a result, we see so may nodes in the Dom Canvas Tree such as
flt-transform, which corresponds to Transform and other layers also follow the same pattern.
Now, let us also look into the advantages and disadvantages of Flutter:
- Single code base For all
- Supports PWA
- Most of the widgets are accessible for both Mobile and Web
- Most of the Plugins are available for both and others are in progress.
- More Focus on Product than Platform
- Performance not upto the mark
- Cannot Inspect Elements
- Not SEO(Search Engine Optimisation) friendly
- Need to Work on URL Routing
- Code Size and Startup Time
- Need More Debugging progress
I am also adding the resources and links which can help you if you want to dig more in detail.
Thank you for reading.