Compose Mental Model & Phases Quiz

UI › Compose Core

A state value is read inside a Canvas's drawRect call (the drawing lambda). When that state changes, which phases re-run?

Answer: Only the drawing phase

A state read in the drawing phase restarts only drawing; composition and layout are untouched because the UI tree and sizes/positions don't change.

Which statement about recomposition is correct?

Answer: Compose skips composables whose stable inputs haven't changed

Compose skips a composable when its inputs are stable and unchanged (compared via equals). Execution order isn't guaranteed, parents don't force children, and recomposition runs on the main thread today.

Why does Compose require composable functions to be idempotent and side-effect free?

Answer: Because recomposition can skip, restart, run often, and may run in parallel

Recomposition may be skipped, cancelled and restarted, run every frame, and is designed to support parallelism, so side effects inside composables could be dropped, duplicated, or partially applied.

In a for-loop emitting MovieOverview(movie) from the same call site without keys, what happens when a new item is inserted at the top?

Answer: Subsequent items recompose because their positional identity shifts

Without keys, instances are identified by execution order, so inserting at the top shifts every subsequent item's positional identity and forces them to recompose.

Which scenario is the correct way to optimize an Image that offsets based on LazyColumn scroll offset?

Answer: Read the scroll offset inside Modifier.offset { }.

The lambda offset { } reads state during the layout (placement) phase, so each scroll re-runs only layout and drawing, skipping recomposition; the dp overload reads in composition and recomposes on every scroll.

What determines a composable's identity in the Composition?

Answer: Its call site, plus execution order or an explicit key()

Compose uses the call site (source location) to identify instances; repeated calls from one call site are disambiguated by execution order, or by key() when you provide explicit identity.

Which type would the Compose compiler NOT automatically treat as stable?

Answer: A regular class with a public var of a mutable, non-notifying type

Primitives, String, and MutableState are inferred stable. A class with a mutable public property that doesn't notify Compose of changes breaks the stability contract, so it's treated as unstable.

Compose's programming model is intentionally designed so that one phase may potentially run in parallel across multiple cores. Which phase, and why is that allowed?

Answer: Composition, because composables must be side-effect free and idempotent

Because composables must be side-effect free and idempotent, Compose is free to run composition for independent subtrees in parallel; layout and drawing currently execute on the main thread.

You derive showScrollToTop = listState.firstVisibleItemIndex > 0 from a LazyColumn. What keeps the composable from recomposing on every single scroll pixel while still updating the boolean?

Answer: Wrapping the calculation in derivedStateOf { ... }

derivedStateOf only notifies readers when its computed result actually changes, so recomposition fires when the boolean flips, not on every change of the frequently-updating firstVisibleItemIndex.

What role does remember play in the Compose mental model?

Answer: It stores a slot-table value so it survives recomposition only.

remember stores a value keyed by call site in the slot table and returns it on later recompositions; it is discarded when the composable leaves composition and does not survive configuration changes, for which rememberSaveable is used.

What does annotating a type with @Immutable promise the Compose compiler?

Answer: That its public properties never change after construction, so it is stable

@Immutable is a developer promise that the type's public properties are fixed after construction, so Compose can infer it as stable and skip recomposition when the same instance is passed again.

Which statement about the Compose layout phase is correct?

Answer: Each node is measured once per layout pass, enabling single-pass layout

Compose enforces single-pass measurement, where a parent measures each child once per pass (intrinsics are the explicit escape hatch); deciding what to emit happens in composition, not layout.

In Compose, the guidance 'state flows down, events flow up' primarily describes which idea?

Answer: Unidirectional data flow through state hoisting with callbacks

State hoisting lifts state to a caller that passes the value down and receives updates via callback lambdas, yielding a single source of truth and unidirectional data flow rather than mutable two-way binding.

Back to Compose Mental Model & Phases