Feature Request: Targeted Reactivity with an @isolated block
Motivation
With the introduction of Signals and the push towards a Zoneless architecture, Angular's reactivity has become significantly more robust. However, change detection is still somewhat tied to the component tree. As explicitly mentioned in the core codebase (packages/core/src/render3/reactive_lview_consumer.ts), all embedded views currently share a consumer with the component view.
This means that if a signal changes deep within a heavy component, the entire component's template must be re-evaluated. For large data grids, dashboards, or complex forms, this lack of fine-grained DOM updates can lead to performance bottlenecks, forcing developers to artificially split their templates into smaller sub-components just for the sake of performance.
Proposed Solution
I propose introducing an @isolated (or @reactive, @memo) control flow block that grants its embedded view its own independent reactive consumer.
<heavy-dashboard>
<!-- Lots of static or heavy DOM elements here -->
@isolated {
<!-- If `clockSignal()` changes, ONLY this embedded view is refreshed.
The parent <heavy-dashboard> component is completely bypassed. -->
<div class="clock">{{ clockSignal() }}</div>
}
</heavy-dashboard>
Technical Implementation Details
The foundation for this feature already exists within Ivy's renderer.
- Compiler: The compiler would transform the
@isolated block into a standard embedded view (similar to @if), but tag it with a specific flag or a new TViewType (e.g., TViewType.Isolated).
- Core / Reactivity: In
packages/core/src/render3/reactive_lview_consumer.ts, we can update the viewShouldHaveReactiveConsumer function:
export function viewShouldHaveReactiveConsumer(tView: TView) {
// Allow the new isolated block to get its own reactive consumer node
return tView.type !== TViewType.Embedded || tView.type === TViewType.Isolated;
}
By allowing this specific embedded view to have its own ReactiveLViewConsumer, signal updates within the block will dirty only that specific node, achieving true fine-grained, localized DOM updates without the overhead of creating a full Angular Component.
Alternatives Considered
- Extracting to a Component: This is the current workaround. However, creating a new component just for fine-grained reactivity introduces unnecessary boilerplate, input/output wiring, and fragmented logic for what should just be a simple localized UI update.
- Signal Components: While signal components (if they arrive) might solve this at the component level, the
@isolated block solves it elegantly at the template level, providing immediate value for developers migrating to signals in existing large components.
Feature Request: Targeted Reactivity with an
@isolatedblockMotivation
With the introduction of Signals and the push towards a Zoneless architecture, Angular's reactivity has become significantly more robust. However, change detection is still somewhat tied to the component tree. As explicitly mentioned in the core codebase (
packages/core/src/render3/reactive_lview_consumer.ts), all embedded views currently share a consumer with the component view.This means that if a signal changes deep within a heavy component, the entire component's template must be re-evaluated. For large data grids, dashboards, or complex forms, this lack of fine-grained DOM updates can lead to performance bottlenecks, forcing developers to artificially split their templates into smaller sub-components just for the sake of performance.
Proposed Solution
I propose introducing an
@isolated(or@reactive,@memo) control flow block that grants its embedded view its own independent reactive consumer.Technical Implementation Details
The foundation for this feature already exists within Ivy's renderer.
@isolatedblock into a standard embedded view (similar to@if), but tag it with a specific flag or a newTViewType(e.g.,TViewType.Isolated).packages/core/src/render3/reactive_lview_consumer.ts, we can update theviewShouldHaveReactiveConsumerfunction:By allowing this specific embedded view to have its own
ReactiveLViewConsumer, signal updates within the block will dirty only that specific node, achieving true fine-grained, localized DOM updates without the overhead of creating a full Angular Component.Alternatives Considered
@isolatedblock solves it elegantly at the template level, providing immediate value for developers migrating to signals in existing large components.