Lab 21: Deferrable Views (@defer)
📖 Resources
Section titled “📖 Resources”🚀 Starter Code
Section titled “🚀 Starter Code”step-18-album-wholesale-v21-post-signal-form
In this lab you will use Angular’s @defer block to lazily load heavy components only when they are actually needed. You will explore the different trigger types and observe the network impact in the browser’s DevTools.
📝 Instructions
Section titled “📝 Instructions”Step 1: Identify a Heavy Component
Section titled “Step 1: Identify a Heavy Component”Find a component in the app that is rendered below the fold and is relatively expensive to render (e.g., AlbumDetailComponent, chart, or CartSummaryComponent).
Step 2: Wrap the Component with @defer
Section titled “Step 2: Wrap the Component with @defer”Replace the direct template reference with a @defer block:
<!-- Before --><app-album-detail [album]="selected" />
<!-- After -->@defer { <app-album-detail [album]="selected" />} @loading { <p>Loading details…</p>} @placeholder { <div class="placeholder-box">Hover to preview</div>} @error { <p>Could not load component.</p>}Step 3: Experiment with Triggers
Section titled “Step 3: Experiment with Triggers”Test each trigger by modifying the @defer line:
<!-- Load when the browser is idle -->@defer (on idle) { ... }
<!-- Load when the block enters the viewport -->@defer (on viewport) { ... }
<!-- Load when the user clicks a button --><button #loadBtn>Load details</button>@defer (on interaction(loadBtn)) { ... }
<!-- Load when the user hovers -->@defer (on hover(loadBtn)) { ... }
<!-- Load after a fixed delay -->@defer (on timer(3s)) { ... }
<!-- Load immediately (but in a deferred chunk) -->@defer (on immediate) { ... }Open the browser’s Network tab, filter by JS, and verify that the component’s chunk only downloads when triggered.
Step 4: Add Prefetching
Section titled “Step 4: Add Prefetching”Prefetch the chunk early while still delaying rendering:
@defer (on interaction(loadBtn); prefetch on idle) { <app-album-detail [album]="selected" />} @placeholder { <button #loadBtn>Show details</button>}Observe in the Network tab: the JS chunk is downloaded during idle time, so there is no delay on click.
Step 5: Set Timing Options
Section titled “Step 5: Set Timing Options”Add minimum display time for @loading to avoid flickers:
@defer (on viewport; prefetch on idle) { <app-album-detail [album]="selected" />} @loading (after 200ms; minimum 500ms) { <p>Loading…</p>} @placeholder (minimum 300ms) { <div class="placeholder-box"></div>}Step 6: Verify the Bundle Split
Section titled “Step 6: Verify the Bundle Split”Run the production build and confirm the component is in a separate chunk:
ng buildInspect the output in dist/ — the deferred component should appear as a separate JS file.

