Skip to content

feat: allow deferred attaching and applying of properties during CD#173

Open
edusperoni wants to merge 1 commit into
mainfrom
feat/defer-rendering
Open

feat: allow deferred attaching and applying of properties during CD#173
edusperoni wants to merge 1 commit into
mainfrom
feat/defer-rendering

Conversation

@edusperoni

@edusperoni edusperoni commented Jun 17, 2026

Copy link
Copy Markdown
Collaborator

PR Checklist

What is the current behavior?

During Angular change detection, the renderer applies every native side-effect synchronously and individually: each native property/style/class write happens as the binding is evaluated, and each view is attached to the native (visual) tree the moment it is appended — which is what triggers it to load (create its native view and measure/lay out). For a CD pass that builds or churns a subtree, this means views load incrementally into a live parent, native property setters can run while a subtree is still half-built, and a view created and removed within the same CD pass still loads.

What is the new behavior?

Adds an opt-in mode that batches native side-effects produced during change detection and applies them once, when CD finishes.

  • Hooks into RendererFactory2.begin()/end() (which Angular calls around every CD pass) to open/flush a deferral window.
  • While deferring, native property/style/class/value writes and visual-tree attaches are queued; the logical tree Angular reads back during the same CD pass (parentNode/firstChild/nextSibling/…) is still updated synchronously, so navigation and ordering are unaffected.
  • On flush: properties are applied first (while views are still unloaded), then subtrees are attached — each parent's children are attached in document order (right-to-left walk) so insertion anchors already exist.

Benefits when enabled:

  • A view created and removed within the same CD pass never loads natively at all.
  • A freshly built subtree is attached (and therefore loaded) exactly once instead of incrementally.
  • Native property writes happen once, while the view is still unloaded, and (on Apple) land inside the existing CATransaction wrapping.

Opt in via the bootstrap config:

bootstrapApplication(AppComponent, {
  deferNativeOpsDuringChangeDetection: true,
  // ...
});

or by providing the DEFER_NATIVE_OPS_DURING_CD token directly. It is off by default, so there is no behavior change unless explicitly enabled.

Tests: added a renderer test suite (renderer-tests.spec.ts) covering the deferral mechanics (deferred attach with synchronous logical tree, add-then-remove elimination, right-to-left insertion, moves, property/class coalescing, leftover-flush recovery, load-exactly-once), the feature's inert default, and end-to-end Angular control-flow rendering (@if/@for with track). Also restored/modernized the previously commented-out renderer tests (createElement, attach/detach, listen, component structure, projection, styles).

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 372592bd-43fb-42af-a328-a32909f3028c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/defer-rendering

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@edusperoni edusperoni force-pushed the feat/defer-rendering branch from b45830b to 17b6fb1 Compare June 18, 2026 02:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant