0PricingLogin
Flutter Mobile Development · Lesson

The Three Trees: Widget, Element, and RenderObject

Understand how Flutter reconciles widget, element, and render trees during rebuilds.

Why Three Trees?

When you write Flutter UI, you describe widgets. But the framework actually maintains three parallel trees that work together every frame:

  • Widget tree — immutable configuration objects you build in build().
  • Element tree — the mutable, long-lived bridge that holds state and tracks position in the tree.
  • RenderObject tree — the objects that actually do layout, painting, and hit-testing.

Understanding this split is the key to reasoning about rebuild cost, why const widgets are cheap, and why a misplaced Key can corrupt state.

Widgets Are Immutable Blueprints

A Widget is just a lightweight, immutable description of a piece of UI. It holds no mutable state and is cheap to create and discard. Calling build() throws away the old widget objects and produces fresh ones every time.

Because widgets are throwaway, comparing two widgets is fast. Flutter uses that comparison to decide whether the heavier element and render objects can be reused rather than rebuilt.

class Greeting extends StatelessWidget {
  const Greeting({super.key, required this.name});

  final String name;

  @override
  Widget build(BuildContext context) {
    // A brand-new Text widget is created on every rebuild.
    return Text('Hello, $name');
  }
}

All lessons in this course

  1. The Three Trees: Widget, Element, and RenderObject
  2. Profiling Jank with the DevTools Timeline
  3. RepaintBoundary, Const Widgets, and Rebuild Pruning
  4. Shader Warm-Up and Impeller Migration
← Back to Flutter Mobile Development