@defer blocks compile without a dependency-resolver function. Deferred components stay as static top-level imports — the block defers rendering but does zero code-splitting.
Repro
import { Component } from '@angular/core';
import { LazyCmp } from './lazy';
@Component({ selector: 'app-parent', imports: [LazyCmp], template: '@defer { <app-lazy/> }' })
export class Parent {}
Actual
LazyCmp kept as a static import; ɵɵdefer(1, 0) receives no dependency-resolver argument; no import('./lazy') anywhere.
Expected
Angular emits a deferred dependency function — () => [import('./lazy').then(m => m.LazyCmp)] — wired into ɵɵdefer, so the chunk is code-split. Aliased imports must use the original export name (m.HeavyWidget, not the local alias); default imports use m.default.
Impact
@defer provides no bundle benefit — its entire purpose. Renders correctly, but a headline Angular feature is silently inert.
Researched and drafted with Claude Code.
@deferblocks compile without a dependency-resolver function. Deferred components stay as static top-level imports — the block defers rendering but does zero code-splitting.Repro
Actual
LazyCmpkept as a static import;ɵɵdefer(1, 0)receives no dependency-resolver argument; noimport('./lazy')anywhere.Expected
Angular emits a deferred dependency function —
() => [import('./lazy').then(m => m.LazyCmp)]— wired intoɵɵdefer, so the chunk is code-split. Aliased imports must use the original export name (m.HeavyWidget, not the local alias); default imports usem.default.Impact
@deferprovides no bundle benefit — its entire purpose. Renders correctly, but a headline Angular feature is silently inert.Researched and drafted with Claude Code.