Basic @defer Usage
@defer loads its template only when the trigger condition is met, reducing initial bundle size and improving page load.
Basic @defer
@Component({
selector: 'app-dashboard',
template: `
<h1>Dashboard</h1>
@defer {
<app-heavy-chart />
} @placeholder {
<p>Chart will appear here...</p>
}
`,
})
export class DashboardComponent {}
@defer Blocks
@defer {
<!-- Main content: loaded when trigger fires -->
<app-heavy-component />
} @placeholder {
<!-- Shown before the trigger fires -->
<p>Loading...</p>
} @loading {
<!-- Shown while the deferred chunk downloads -->
<p>Downloading...</p>
} @error {
<!-- Shown if loading fails -->
<p>Failed to load component</p>
}
Trigger Types
| Trigger | When It Fires |
|---|---|
@defer (default) |
When the browser is idle |
@defer (on idle) |
When the browser is idle |
@defer (on viewport) |
When the element enters the viewport |
@defer (on interaction) |
When the user clicks/taps the placeholder |
@defer (on hover) |
When the user hovers the placeholder |
@defer (on timer) |
After a specified delay |
@defer (on immediate) |
Immediately after the page loads |
Defer Triggers in Detail
Triggers control when deferred content loads. Choose the right trigger for each scenario.
viewport Trigger
Loads when the element enters the viewport (uses Intersection Observer):
@defer (on viewport) {
<app-image-gallery />
} @placeholder {
<div class="skeleton-loader"></div>
}
interaction Trigger
Loads when the user interacts with the placeholder:
@defer (on interaction) {
<app-comments />
} @placeholder {
<button>Load Comments</button>
}
timer Trigger
Loads after a specified delay:
@defer (on timer(5s)) {
<app-newsletter-signup />
} @placeholder {
<p>Newsletter will appear in 5 seconds...</p>
}
hover Trigger
Loads when the user hovers over the placeholder:
@defer (on hover) {
<app-tooltip-content />
} @placeholder {
<span>Hover for details</span>
}
Combining Triggers
@defer (on interaction; on timer(10s)) {
<app-recommendations />
} @placeholder {
<p>Click here or wait 10 seconds</p>
}
Practical Example: E-commerce Product Page
<div class="product-page">
<h1>{{ product.name }}</h1>
<p>{{ product.price | currency }}</p>
<!-- Heavy reviews section deferred until visible -->
@defer (on viewport) {
<app-product-reviews [productId]="product.id" />
} @placeholder {
<div class="reviews-skeleton"></div>
}
<!-- Newsletter signup deferred until idle -->
@defer (on idle) {
<app-newsletter-signup />
} @placeholder {
<div class="newsletter-placeholder"></div>
}
</div>
Performance Benefits
- Smaller initial bundle — Deferred components are separate chunks
- Faster initial paint — Only essential content loads first
- Bandwidth savings — Heavy components download only when needed
- Better Core Web Vitals — Improved LCP and INP
Quiz
1. What does @defer do?
2. Which trigger loads content when it enters the viewport?
3. What is the default trigger for @defer?
Flashcards
Question
What does @defer do?
Click to reveal answer
Answer
Loads template content only when a trigger fires. Reduces initial bundle size.
Question
Which trigger for viewport loading?
Click to reveal answer
Answer
on viewport — uses Intersection Observer.
Question
What is the default @defer trigger?
Click to reveal answer
Answer
on idle — loads when browser is idle.
Revision Notes
Key Takeaways
- 1. @defer loads content only when a trigger fires
- 2. Triggers: idle, viewport, interaction, hover, timer, immediate
- 3. Placeholder, loading, and error blocks handle all states
- 4. Reduces initial bundle size and improves Core Web Vitals
Interview Tips
- • Explain the performance benefits of deferred loading
- • Be ready to describe each trigger type
- • Mention Core Web Vitals improvements
Cheat Sheet
@defer Cheat Sheet
Basic:
@defer {
<app-heavy />
} @placeholder {
<p>Loading...</p>
}
Triggers:
on idle(default)on viewporton interactionon hoveron timer(5s)on immediate
Blocks:
- @placeholder — before trigger
- @loading — while downloading
- @error — on failure