flitter-ui (지금 베타입니다)

Understanding the RenderObject System

Flitter uses the same rendering architecture as Flutter. To draw something on the screen, you need to understand three tree structures.

Widget Tree, Element Tree, and RenderObject Tree

Role of Each Tree

Widget Tree (Blueprint)

  • Immutable objects that declaratively express UI structure
  • Code written by developers
  • Can be recreated every frame

Element Tree (Instance)

  • Intermediate layer connecting Widget and RenderObject
  • Manages state and handles lifecycle
  • Elements are reused even when Widgets change

RenderObject Tree (Rendering)

  • Handles actual layout calculation and drawing
  • Contains size, position, and painting information
  • Performance-critical part, reused whenever possible

Separation of Layout and Paint

performLayout(): Size and Position Calculation

class RenderBox {
  performLayout() {
    // 1. Perform layout for children
    // 2. Determine own size based on children's sizes
    // 3. Determine children's positions
  }
}

paint(): Actual Drawing on Screen

class RenderBox {
  paint(context: PaintingContext, offset: Offset) {
    // 1. Draw own content (background, borders, etc.)
    // 2. Request paint from children
  }
}

Why Are They Separated?

Layout and Paint are separated for performance optimization:

  1. Layout Caching: Layout is not recalculated if size or position doesn't change
  2. Partial Repaint: Only paint is performed without layout when only colors change
  3. Layer Optimization: Unchanged parts are cached as layers

Exploring the Source Code

Flitter's RenderObject implementation can be found in the packages/flitter/src/renderobject/ directory:

  • RenderObject.ts: Base RenderObject class
  • RenderBox.ts: RenderBox implementing 2D box model
  • RenderFlex.ts: Flex layout that forms the basis of Row and Column

Looking at the actual implementation, you can see it has almost identical structure to Flutter.