Flutter’s UI Framework: Deep Dive Into Its Internals

RapidFork Technology
5 min readNov 2, 2023

--

Flutter, Google’s UI toolkit, has rapidly gained popularity for its ability to build natively compiled applications for mobile, web, and desktop from a single codebase. At the heart of Flutter is its rich UI framework, allowing developers to create visually stunning applications. But how does it all work under the hood? Let’s embark on a journey to unravel the depths of Flutter’s UI framework, enabling you to harness its full potential.

The Layered Architecture

Flutter’s architecture is modular and layered, offering a hierarchy of libraries:

  1. Framework: The Dart-based, high-level set of libraries that most developers interact with directly.
  2. Engine: Written primarily in C++, this bridges the gap between the framework and Skia.
  3. Embedder: This platform-specific code embeds the Flutter app into its respective environment (iOS, Android, web).

Understanding this layered approach is pivotal for optimizing performance and ensuring smooth user experiences.

Widgets: The Building Blocks

Everything in Flutter starts and ends with widgets. They’re the fundamental building blocks of your application’s UI.

Element & Render Trees

Widgets describe how the UI should look, but they’re ephemeral. Flutter uses widgets to produce and update the Element Tree and the Render Tree:

  • Element Tree: Represents a runtime instance of a widget. It’s what you’d get if you walked through the widget tree and instantiated each widget.
  • Render Tree: Contains the visual aspects of widgets. Each RenderObject knows how to paint itself and lay out its children.

The Lifecycle of a Widget

Widgets have a short-lived lifecycle. When the state or data changes, instead of updating the existing widget, Flutter creates a new widget. This immutability ensures consistency and simplicity in the UI description but raises the question: “Isn’t that inefficient?” The magic answer lies in Flutter’s diffing algorithm, which efficiently compares the old and new widget trees and updates only the differences.

Painting: The Skia Connection

Flutter’s engine contains the Skia graphics library, a high-performance, open-source 2D graphics library. Every visual element you see in a Flutter app is a series of Skia commands.

Custom Painting

For custom graphics, developers often use the CustomPainter class. Every draw method on its Canvas (e.g., drawCircle, drawPath) translates to Skia commands. This direct connection with Skia ensures that Flutter's painting operations are fast and efficient.

Layout & Constraints

In Flutter, layout is a two-pass system:

  1. Parent to Child: Parents set constraints (minimum and maximum width and height) for their children.
  2. Child to Parent: Children, after laying out, inform their parents of their size.

This system ensures that, even with complex layouts, Flutter can quickly determine the size and position of each widget on the screen.

Gestures & Interactivity

Flutter’s gesture system is a crucial aspect of its interactive prowess. Raw pointer events are captured and passed through a series of Gesture Recognizers. These recognizers determine specific gestures (tap, double-tap, swipe). An arena system ensures that, in case of conflicting gestures, only one recognizer wins.

Deep Insights: Performance & Customization

  • Repaint Boundaries: Not all widgets need to be redrawn all the time. Repaint boundaries isolate sections of the widget tree, ensuring that changes in one section don’t unnecessarily repaint other sections.
  • Custom Widgets: Understanding the basics of the RenderObject system can empower you to create custom widgets from scratch. For instance, if you're building a unique shape or a complex visual element, diving deep into the rendering layer can be beneficial.
  • Platform Channels: For platform-specific code, Flutter offers platform channels. While not strictly UI-related, they’re crucial for apps that need deeper integration with OS-specific features.

Diffing algorithms

Flutter’s diffing algorithm is a fundamental part of its performance optimizations, especially when updating the UI. Unlike some other frameworks that use a virtual DOM and compare differences there, Flutter operates directly on the widget tree. The process is quite different and interesting. Let’s dive into it:

Widget Reconstruction

In Flutter, widgets are lightweight and immutable. When the state of an application changes, Flutter doesn’t modify existing widgets. Instead, it rebuilds the widget tree. This might seem inefficient at first, but due to the lightweight nature of widgets and Flutter’s efficient diffing algorithm, this process is highly optimized.

Element Tree: The Stable Backbone

While widgets are ephemeral, the element tree remains stable. Each widget can create an Element object that remains in memory over time. The Element acts as a persistent handle to a location in the widget tree.

When Flutter rebuilds the widget tree, it tries to match the newly built widgets with the existing elements. This process is where the diffing comes into play.

Diffing Process

  1. Keyed Matching: Widgets can have an optional Key property. If a widget has a key, Flutter can quickly and accurately match the widget to its corresponding element, even if the widget's position in the tree has changed. This is especially useful for lists where items might be added, removed, or reordered.
  2. Type Matching: If no key is provided, Flutter tries to match widgets and elements based on their runtime type. If a widget of the same type is found in the same location as before, Flutter will reuse the element.
  3. Reconciliation: After matching, any unmatched elements are unmounted (i.e., removed from the tree). New widgets that don’t match any existing element result in the creation of new elements.
  4. Component Update: For matched elements, Flutter calls the update method, passing in the new widget. This step is where properties might be updated, and the underlying render tree might be marked as "dirty" to schedule a repaint.
  5. Render Tree Update: Changes in the widget or element tree may lead to updates in the render tree. The render tree, being more heavyweight, is updated selectively. Only “dirty” nodes (those that need layout or painting updates) are reprocessed. This ensures that only necessary graphics operations are sent to the GPU.

Benefits

  • Performance: By reusing elements and render objects, Flutter avoids unnecessary object creation and garbage collection. This leads to smoother animations and interactions.
  • State Preservation: Stateful widgets hold state that might not change even if the widget rebuilds. By reusing elements and associated stateful widgets, Flutter ensures that state is preserved across rebuilds.
  • Explicit Control: Developers have fine-grained control over the diffing process using keys. This ensures that even in complex scenarios, like list animations, the UI updates as intended.

Flutter’s diffing algorithm is a core part of its reactive UI paradigm. By efficiently matching new widgets with existing elements and selectively updating the render tree, Flutter achieves high performance while providing developers with a simple and intuitive UI description mechanism. This approach contrasts with the virtual DOM diffing used in some web frameworks but is well-suited for the specific challenges and opportunities of mobile app development.

So

Flutter’s UI framework is a testament to its power and flexibility. By understanding its internals, from the widget lifecycle to the Skia rendering engine, developers can make informed decisions, optimize performance, and truly harness the potential of this remarkable framework.

Empower yourself with this knowledge, and you’ll not only build beautiful Flutter apps but also efficient and high-performance ones. Whether you’re selecting components, structuring your application, or designing widgets from scratch, a deep understanding of Flutter’s internals will always guide you to the best solutions.

--

--

RapidFork Technology
RapidFork Technology

Written by RapidFork Technology

Innovation, Creativity and Change | Visit us: www.rapidfork.com

No responses yet