-
Notifications
You must be signed in to change notification settings - Fork 38
docs: add deep dive into flutter architecture trees #565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
AbhishekDoshi26
wants to merge
15
commits into
main
Choose a base branch
from
feat/flutter-concepts
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
8fe5e25
docs: add conceptual guide explaining the Flutter three-tree architec…
AbhishekDoshi26 bc311aa
Update src/content/docs/flutter-concepts/architecture-trees.mdx
AbhishekDoshi26 1c1b4cb
docs: Update src/content/docs/flutter-concepts/architecture-trees.mdx
AbhishekDoshi26 bf95c5e
Merge branch 'main' into feat/flutter-concepts
AbhishekDoshi26 1f740cd
fix PR review comments
AbhishekDoshi26 fce0224
fix: add link to flutter performance docs
AbhishekDoshi26 37b9962
fix: Update src/content/docs/flutter-concepts/architecture-trees.mdx
AbhishekDoshi26 5eeed51
fix: Update src/content/docs/flutter-concepts/architecture-trees.mdx
AbhishekDoshi26 23c37c0
fix: Update src/content/docs/flutter-concepts/architecture-trees.mdx
AbhishekDoshi26 98c0ee7
fix: mention State object earlier in Element Tree section
AbhishekDoshi26 74dbfe0
fix: remove fluff sentence from RenderObject section
AbhishekDoshi26 5d7ace5
fix: address PR feedback regarding bolding, fluff, and conclusion flow
AbhishekDoshi26 eb79441
Merge branch 'main' into feat/flutter-concepts
AbhishekDoshi26 b692a68
docs: reformat text for improved readability in architecture-trees.mdx
AbhishekDoshi26 570c1e7
Update src/content/docs/flutter-concepts/architecture-trees.mdx
tomarra File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
153 changes: 153 additions & 0 deletions
153
src/content/docs/flutter-concepts/architecture-trees.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| --- | ||
| title: 'Architecture Trees' | ||
| description: | ||
| A deep dive into the three-tree architecture that powers Flutter, explained by | ||
| the creator. | ||
| sidebar: | ||
| order: 5 | ||
| --- | ||
|
|
||
| If you’ve spent any time with Flutter, you’ve probably heard the phrase: | ||
| _"Everything is a widget."_ While that's a fantastic way to think about building | ||
| your app, it's not the whole story. If you want to build really smooth, | ||
| high-performing apps, it helps to peek under the hood and see what's actually | ||
| happening. | ||
|
|
||
| When the Flutter framework was designed, there was a distinct goal: | ||
| **[keep things consistently fast and smooth at 60 (or even 120) frames per second.](https://docs.flutter.dev/perf)** | ||
| To pull that off, Flutter avoids using a single, heavy structure (like the DOM | ||
| in web development). Instead, it uses a team of three different "trees" working | ||
| together: the **Widget Tree**, the **Element Tree**, and the **RenderObject | ||
| Tree**. | ||
|
|
||
| Let's break down what each tree does and how they team up to paint pixels on | ||
| your screen. | ||
|
|
||
| ```mermaid | ||
| graph TD | ||
| W["Widget Tree<br>(The Blueprints)"] --> E["Element Tree<br>(The State Managers)"] | ||
| E --> R["RenderObject Tree<br>(The Workhorses)"] | ||
|
|
||
| style W fill:#e1f5fe,stroke:#03a9f4,stroke-width:2px,color:#000 | ||
| style E fill:#e8f5e9,stroke:#4caf50,stroke-width:2px,color:#000 | ||
| style R fill:#fff3e0,stroke:#ff9800,stroke-width:2px,color:#000 | ||
| ``` | ||
|
|
||
| ## 1. The Widget Tree: Your Blueprints | ||
|
|
||
| Widgets are what you write every day: `Container`, `Text`, `Row`, `Column`, and | ||
| so on. | ||
|
|
||
| But what _is_ a Widget, really? **Think of a widget as an immutable blueprint.** | ||
|
|
||
| Widgets don't actually draw anything on the screen. They are super lightweight | ||
| Dart objects that just hold configuration data, like "this should be blue" or | ||
| "this needs 10 pixels of padding." Because they are just simple data containers | ||
| and never change (immutable), Flutter can toss them out and rebuild millions of | ||
| them every second without breaking a sweat. | ||
|
|
||
| When you call `setState()`, you aren’t directly telling the screen to redraw. | ||
| You are just telling Flutter to throw away the old stale objects and create new | ||
| ones from the blueprints you created. | ||
|
|
||
| ## 2. The Element Tree: The State Manager | ||
|
|
||
| If widgets are just temporary blueprints, how does Flutter remember anything? | ||
| How does it keep track of an animation playing, or what you typed into a text | ||
| field? | ||
|
|
||
| Enter the **Element Tree** (where your `State` lives!). | ||
|
|
||
| For every Widget you put in your app, Flutter creates a corresponding | ||
| **Element**. You can think of the Element Tree as the brain or the skeleton of | ||
| your app. Unlike widgets, **Elements stick around and can change over time.** | ||
| For `StatefulWidgets`, the Element is what actually holds onto the `State` | ||
| object you interact with daily. | ||
|
|
||
| When a new Widget Tree is built, Flutter doesn't throw away the Element Tree. | ||
| Instead, it looks at the new blueprints and compares them to the existing | ||
| Elements: | ||
|
|
||
| - If the new widget looks like the old one (same type and key), the Element just | ||
| says, "Cool, I'll update my settings" and stays right where it is. | ||
| - If the widget type completely changed, the old Element is tossed out, and a | ||
| brand new one takes its place. | ||
|
|
||
| This is the secret to Flutter's speed! The Element Tree manages the lifecycle | ||
| and acts as the smart middleman that decides when actual heavy lifting needs to | ||
| be done. | ||
|
|
||
| ## 3. The RenderObject Tree: The Workhorse | ||
|
|
||
| Finally, we have the **RenderObject Tree**. | ||
|
|
||
| While Widgets hold the blueprints and Elements manage the brains, RenderObjects | ||
| do the heavy lifting: **figuring out exactly how big things are, where they go | ||
| on the screen, and painting the actual pixels.** | ||
|
|
||
| For every visual Element in your app, there's a RenderObject. These are heavy | ||
| and expensive to create, which is exactly why the Element Tree protects them. | ||
| RenderObjects contain all the complicated math needed to measure constraints and | ||
| tell the graphics engine how to draw. | ||
|
|
||
| If you change a `Container` from blue to red, the Widget is recreated, the | ||
| Element updates its state, but the _exact same_ RenderObject is kept around; | ||
| it's simply told, "Hey, next time you draw, use red paint instead of blue." | ||
|
|
||
| ## The Lifecycle: Putting It All Together | ||
|
|
||
| Let's walk through what happens when you tap a button that changes a color: | ||
|
|
||
| 1. **You tap the button**: `setState()` is called. | ||
| 2. **New Blueprints**: Flutter asks your `build` method for new widgets. A new | ||
| Widget Tree is spun up instantly. | ||
| 3. **Checking the Changes**: The Element Tree looks at the new widgets and | ||
| compares them to the old ones. It notices that only a color changed. | ||
| 4. **Passing the Message**: The Element updates its internal reference to the | ||
| new widget and passes the message down to its RenderObject about the new | ||
| color. | ||
| 5. **Painting**: The RenderObject marks itself as needing a fresh coat of paint | ||
| (`markNeedsPaint()`). On the very next frame, the engine asks that specific | ||
| RenderObject to redraw itself, leaving everything else untouched. | ||
|
|
||
| ## The Secret Identity of BuildContext | ||
|
|
||
| If you've written any Flutter code, you've seen this: | ||
|
|
||
| ```dart | ||
| @override | ||
| Widget build(BuildContext context) { | ||
| return Container(); | ||
| } | ||
| ``` | ||
|
|
||
| You might have wondered, _"What exactly is that `context` thing?"_ | ||
|
|
||
| Here is the biggest "Aha!" moment for most Flutter beginners: **`BuildContext` | ||
| is actually just the Element!** | ||
|
|
||
| When Flutter asks your widget to build itself, it hands you the `BuildContext`. | ||
| It's just the Element saying, "Here I am in the tree! If you need to find an | ||
| ancestor widget (like a `Theme` or a `Navigator`), you can use me to look up the | ||
| tree." | ||
|
|
||
| ## Why This Matters | ||
|
|
||
| By splitting the work into blueprints (Widgets), brains (Elements), and brawn | ||
| (RenderObjects), Flutter gives you a really friendly way to code without giving | ||
| up any of that sweet native-level performance. | ||
|
|
||
| Understanding this team of three trees makes you a much better Flutter | ||
| developer: | ||
|
|
||
| - You'll understand why | ||
| [`Keys`](https://api.flutter.dev/flutter/foundation/Key-class.html) are | ||
| sometimes needed (they help the Element tree match up widgets correctly when | ||
| you reorder lists). | ||
| - You'll realize why creating lots of widgets is totally fine, but stacking | ||
| unnecessary deep widgets like | ||
| [`Opacity`](https://api.flutter.dev/flutter/widgets/Opacity-class.html) or | ||
| [`Clip`](https://api.flutter.dev/flutter/widgets/ClipRect-class.html) (which | ||
| create heavy RenderObjects) can slow things down. | ||
| - You'll know exactly what's happening under the hood, making debugging and | ||
| optimizing a breeze. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.