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 → RenderObject Tree
Three Tree Structures
Widget is the blueprint, Element is the instance, and RenderObject handles the actual rendering
// Widget Tree (개발자가 작성하는 코드)
Container({
child: Text("Hello")
})
// Element Tree (프레임워크가 자동 생성)
ContainerElement -> TextElement
// RenderObject Tree (실제 렌더링)
RenderDecoratedBox -> RenderParagraph
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
Layout and Paint Process
performLayout() calculates size and position, paint() does the actual drawing
Layout Phase
performLayout() {
// 1. 자식에게 제약 전달
child.layout(constraints);
// 2. 자신의 크기 결정
size = computeSize(child.size);
// 3. 자식 위치 결정
child.offset = computeOffset();
}
Paint Phase
paint(context, offset) {
// 1. 배경 그리기
context.drawRect(rect, paint);
// 2. 자식 그리기
child.paint(context, childOffset);
// 3. 전경 그리기
context.drawBorder(border);
}
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:
- Layout Caching: Layout is not recalculated if size or position doesn’t change
- Partial Repaint: Only paint is performed without layout when only colors change
- 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 classRenderBox.ts
: RenderBox implementing 2D box modelRenderFlex.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.
Next Steps
Now that you understand the basic concepts of RenderObject, in the next chapter we’ll explore the Constraints system, which is the core of layout. We’ll examine in detail how constraints are passed from parent to child and how sizes are determined.