Angular’s @defer block loads its content and dependencies lazily, triggered by a condition such as entering the viewport or an idle moment. It is a template-level code-splitting tool: the deferred component and everything it imports move into a separate chunk.
Before you start
You should be comfortable with Angular templates and standalone components. This article assumes a recent Angular version that supports @defer.
Step-by-step walkthrough
Step 1: Wrap the heavy region
Put the expensive component inside @defer { ... } and provide an @placeholder for the space it will occupy. The placeholder gives the layout a stable shape and a fallback while the chunk loads.
Step 2: Pick a trigger that matches intent
on viewport loads when the element scrolls into view, on idle waits for the browser to be free, on interaction waits for a click, and on timer(5s) waits a fixed delay. Prefetching with prefetch on idle starts the download earlier while still deferring render, which balances perceived speed and work.
Step 3: Keep critical content eager
Do not defer content that is above the fold or needed for the primary task; deferring it adds a network round trip before the user sees it. Defer secondary widgets, charts and below-the-fold sections instead.
Worked scenario
The chart loads only when it scrolls into view.
@defer (on viewport) {
<sales-chart [data]="sales" />
} @placeholder {
<div class="chart-skeleton"></div>
} @loading (minimum 200ms) {
<span>Loading chart…</span>
}Walk through the example
on viewport defers the chart until it is visible, so the chunk is not requested on first paint. The placeholder reserves the space, avoiding layout shift, and @loading shows feedback with a minimum time so a fast load does not flash. The sales-chart component and its dependencies land in a lazy chunk.
Common mistake
Deferring a component that is immediately visible, which delays useful content, or omitting the placeholder and causing a layout shift when the region appears. Another is expecting @defer to help when the deferred component is imported eagerly elsewhere, since it is then already in the main bundle.
Verify the behavior
Build the app and check the output for a separate chunk for the deferred component. In the browser, confirm the chunk is requested only when the trigger fires. Measure cumulative layout shift with and without the placeholder to confirm the placeholder reserves space.
Interview exercise
A dashboard shows a large heatmap below the fold. How would you apply @defer?
Answer and reasoning
Wrap the heatmap in @defer (on viewport) with a placeholder sized to the chart and a loading state, so it downloads only when scrolled to. Use prefetch on idle if the user is likely to scroll soon, accepting an earlier download in exchange for a faster reveal. Keep the KPI cards above eager, since they are the first thing the user needs.
Continue learning
Compare timing with Angular view query timing and signals. Read the Angular deferred loading guide and try the Angular interview questions.