This document provides a detailed explanation of the rendering mechanism implemented in the library, focusing on the Component and CoreComponent classes and their lifecycles.
Note: This document is part of a series on the rendering architecture. See also Component Lifecycle, Scheduler System, and the integration document Component Rendering and Lifecycle Integration.
The rendering mechanism is built upon a hierarchical tree structure with the following key components:
- Tree - The base hierarchical structure that manages parent-child relationships with z-index ordering
- CoreComponent - The fundamental component class that implements tree traversal and child management
- Component - Extends CoreComponent to add lifecycle hooks and state management
- Scheduler - Manages the timing of updates and traversal of the component tree
The Tree class provides the foundational hierarchy structure with:
- Parent-child relationship management
- Z-index based ordering of children
- Traversal methods for walking the tree
CoreComponent is the base component class that:
- Implements the
ITreeinterface - Manages the tree structure for components
- Handles the creation, updating, and removal of child components
- Provides the basic update and render architecture
Component extends CoreComponent to add:
- State management
- Comprehensive lifecycle hooks
- Control flags for rendering optimization
- More fine-grained control over the rendering process
The Scheduler orchestrates the rendering process by:
- Managing request animation frame (rAF) timing
- Traversing the component tree
- Triggering component iterations
- Providing global and component-level scheduling
The rendering process follows these steps:
- Component state/props update via
setState/setProps performRender()schedules an update through theScheduler- On the next animation frame,
Schedulertraverses the component tree - Each component's
iterate()method is called - Components process their data and execute their lifecycle methods
- Child components are created, updated, or removed as needed
- The process repeats for each animation frame when changes occur
The rendering mechanism relies on component lifecycle methods to manage the rendering process. The lifecycle methods are documented in detail in Component Lifecycle.
Key integration points between the rendering system and component lifecycle:
- Components use
render()to produce visual output - Component trees are traversed in z-index order
- Visual output is coordinated through the
iterate()method - State/props changes trigger rendering through
performRender()
See Component Rendering and Lifecycle Integration for a comprehensive view of how these systems interact.
Components manage their state and props using a buffered approach:
- When
setStateorsetPropsis called, changes are stored in a temporary buffer (__data) - The component schedules a render update via
performRender() - On the next animation frame, the buffered changes are applied to the actual state/props during the
checkData()method - Lifecycle callbacks like
propsChanged()andstateChanged()are triggered as needed
This approach allows for batching multiple state/props updates into a single render cycle, improving performance.
For more details on this process, see Component Lifecycle.
The z-index system uses a two-tier stacking model that separates component type priority from visual stacking order within the same type.
zIndex encodes the architectural importance of a component class. Different component types are assigned different base values:
- Blocks have a higher
DEFAULT_Z_INDEXthan connections - Connections render above group backgrounds
- When two components of different types overlap, the one with the higher
zIndexalways wins, regardless of render order
This value is set per component class in graphConfig.ts and changed via updateZIndex() (e.g., when a block is selected or dragged, its zIndex is incremented to rise above its unselected peers).
renderOrder determines stacking within the same zIndex tier. It is assigned by the scheduler during _walkDown traversal: the later a component is visited in the tree, the higher its renderOrder.
Tree.updateChildZIndex() is the key mechanism: every time a component's zIndex changes, the child is re-inserted at the end of the parent's children Set (delete + add). Because the children Set preserves insertion order, the most recently interacted component gets the highest renderOrder in its tier — it appears on top visually.
This means drag-and-drop and selection automatically bring the interacted block to the front of its z-group without any extra bookkeeping.
HitTest.testHitBox() sorts candidates by both criteria (descending — highest = topmost):
- First by
zIndex(type priority) - Then by
renderOrder(within-type visual stacking)
The first element of the returned array is the component the user most likely intended to interact with.
| Criterion | Controls | Set by |
|---|---|---|
zIndex |
Which component type wins | updateZIndex(), class constant |
renderOrder |
Which instance wins within its type | Scheduler traversal order + updateChildZIndex() |
The rendering mechanism integrates with the browser's animation frame:
- GlobalScheduler manages requestAnimationFrame
- Component updates are scheduled within animation frames
- Multiple schedulers can be registered with different priorities
- The system aims to complete updates within the 16ms frame budget
constructor(props, parent)- Create a component instanceperformRender()- Schedule a render updatesetContext(context)- Update the contextiterate()- Process component updatesstatic create(props, options)- Factory methodstatic mount(Component, props)- Mount a component as rootstatic unmount(instance)- Unmount a component
-
setState(state)- Update component state -
setProps(props)- Update component props -
Additional lifecycle hooks:
willMount()- Before first iterationwillRender()- Before renderingdidRender()- After renderingwillIterate()- Before iterationdidIterate()- After iterationwillUpdateChildren()- Before updating childrendidUpdateChildren()- After updating childrenpropsChanged(nextProps)- When props changestateChanged(nextState)- When state changes
- Component Lifecycle - In-depth details about component lifecycle methods
- Scheduler System - Explanation of the scheduling and update system
- Component Rendering and Lifecycle Integration - Comprehensive guide showing how these systems work together