Question presented to candidate: "A teammate says Angular 're-renders everything whenever anything happens'. Walk me through how change detection actually decides what to update in a current Angular app, and what would make a value on screen go stale."
What a strong answer should cover:
- Change detection is Angular re-running compiled template code for a view and patching only the DOM bindings whose values changed; there is no virtual DOM diff.
- A run walks the component tree top-down, but each view is checked only if it is dirty (or is an
Eagercomponent reached by the walk). - What marks a view dirty: a signal read in its template changing, a template or host event,
markForCheck()(also called byAsyncPipe),ComponentRef.setInput. - v22 defaults: OnPush is the default strategy,
Eageris the opt-in old behaviour andDefaultis a deprecated alias; apps are zoneless by default since v21, so nothing schedules a run "because a timer fired". - Dev mode runs a second check pass and throws
NG0100 ExpressionChangedAfterItHasBeenCheckedErrorif a binding changed during the first. - Practical consequence: state the template reads should be a signal; a plain field mutated in a
setTimeoutstays stale.
Clarifying questions expected:
- "Is this a zoneless app (the v21+ default) or one that opted back into Zone.js?"
- "Are the components on the v22 default (OnPush) or migrated with
ChangeDetectionStrategy.Eager?"
Code / implementation expected: Optional β a small tree that shows which components re-run after a signal change, a click and a plain-field change.