The Rendering Bet Behind Every Mobile UI Framework
Choosing a mobile UI framework without understanding its rendering strategy means fighting its design rather than leveraging it. The cost shows up as jank, unnecessary recomposition, or state bugs that no compiler catches—problems that surface months later in a profiler.
Every UI framework makes a bet on how much screen to redo when state changes. Android Views mutates the tree in place—cheap but demanding manual sync between model and view. Flutter rebuilds the widget tree optimistically, diffs against the previous version, and patches only what changed, eliminating state-UI drift at the cost of wasted construction. Jetpack Compose tracks exactly which composable reads which state object and re-executes only those scopes, avoiding both manual sync and optimistic rebuilds.
The three architectures converge on the same expensive layer—measure, layout, paint—but diverge in how they decide what work to skip. Views skips nothing by default; Flutter decides after rebuilding by comparing results; Compose decides before re-running by comparing inputs. Each choice shifts the developer's burden: Views demands discipline in synchronization, Flutter demands discipline in rebuild scoping, and Compose demands understanding of its invisible stability contract.
Production performance problems rarely come from picking the wrong framework. They come from using one framework while mentally operating in another's model—mutating state imperatively inside Flutter, or hoisting reads unnecessarily inside Compose.
Compose's invisible stability contract is a sharper trade-off than Flutter's visible rebuild cost. A developer who doesn't know the contract exists ships an app that is silently slower, with no crash or lint warning to flag the problem.
The three frameworks converge on the same expensive layer—measure, layout, paint—but diverge entirely in how they decide what work to skip. That decision point is the architecture's real signature.
Flutter's three-tree split (Widgets, Elements, RenderObjects) is not an implementation detail; it is the mechanism that makes optimistic rebuilds viable by protecting the expensive layer from the cheap one.
Compose Multiplatform borrows Flutter's own-every-pixel bet on non-Android platforms, which means two frameworks with opposite philosophies end up sharing the same rendering strategy outside Android.