iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
The @defer block lets you split eligible parts of an Angular template into separate JavaScript chunks and load them only when a trigger fires or a condition becomes true. Used well, it keeps the initial bundle smaller and postpones work the user does not need yet. Used carelessly, it can delay visible content, shift the layout, or hide the component from server-rendered HTML. This guide covers how to write a deferred block, which dependencies qualify, how each trigger behaves, and what changes under server-side rendering.
A minimal deferred block
The simplest form wraps a component in @defer:
@defer {
<large-chart />
}
With no trigger, Angular waits for the browser to become idle, then fetches the chunk and renders the component. Angular’s compiler turns the dependencies inside the block into dynamic imports, which is what allows them to leave the main bundle. A placeholder is optional. If you provide one, it appears before the trigger fires and is replaced once the deferred imports resolve.
Which dependencies can be deferred
A deferred block can cover components, directives, pipes, and the component CSS associated with them. Eligibility has practical limits, and the rules are where most surprises come from:
- The dependency must be standalone. Non-standalone dependencies are loaded eagerly, so deferring them has no effect on the bundle.
- The dependency must not be referenced outside the defer block in the same file. A direct use elsewhere in that file pulls it into the eager bundle.
- The dependency must not be targeted by a
ViewChildquery. Such a query forces eager loading. - The transitive dependencies of an eligible standalone component can still be declared in an NgModule and take part in the deferred load.
Angular does not guarantee the order in which generated dynamic imports resolve, so do not write code that depends on one chunk arriving before another.
#1 Best Overall
Choosing a trigger
The on keyword sets when the content loads. The table below summarises the built-in triggers from Angular’s @defer API reference.
| Trigger | Loads when | Typical use |
|---|---|---|
(none) or on idle |
The browser becomes idle | Secondary content with no urgency |
on viewport |
The placeholder enters the viewport | Content below the fold |
on interaction |
The user clicks or presses a key on the placeholder | Panels opened by a deliberate action |
on hover |
The pointer moves over the placeholder, or it receives focus | Tooltips, flyouts, or menus that users预 expect |
on immediate |
Right after the initial render | Content that should load early but not block first paint |
on timer(<duration>) |
After the given delay, such as timer(2s) |
Content with a known, fixed delay |
when <expression> |
The expression becomes truthy | Application state, such as a feature flag or data availability |
Several triggers can be combined in one block, separated by semicolons. Multiple triggers act as OR conditions: whichever fires first loads the content. The when condition is one-way. Once the expression is truthy, the block loads, and it does not return to the placeholder if the expression later becomes false.
Rank #2
Placeholder, loading, and error states
A deferred block can define three companion sections:
@placeholdershows before the trigger fires. Add(minimum 500ms)to keep a placeholder that is replaced very quickly from flashing on screen.@loadingshows while the chunk downloads. The form(after 100ms; minimum 1s)delays the indicator and keeps it visible for at least a set time.@errorshows if the chunk fails to load. Provide a failure state for this case rather than leaving the area blank.
The timing values are durations such as 100ms or 1s. Keep these sections light. Their dependencies are eager, so a heavy loading spinner or fallback component adds to the initial bundle without helping the user.
Rank #3
@defer (on viewport) {
<product-reviews />
} @placeholder (minimum 500ms) {
<div class="reviews-skeleton"></div>
} @loading (after 100ms; minimum 1s) {
<p>Loading reviews…</p>
} @error {
<p>Reviews could not be loaded. Refresh the page to try again.</p>
}
Chunk-load errors are reported under NG0750. Your @error block is the place to handle them in the UI.
Prefetching: separating download from rendering
A trigger decides when content renders. Prefetching decides when its code is fetched, and it is configured separately. A prefetch on or prefetch when condition can start the download before the render trigger fires, so the content appears without waiting for the network. The cost is earlier network work, which matters on slow connections and for content many users never reach.
Rank #4
@defer (on interaction; prefetch on idle) {
<checkout-summary />
}
In this example the chunk downloads when the browser is idle, but the component only appears after the user interacts with the placeholder.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsServer-side rendering and hydration
By default, server rendering outputs the placeholder, or nothing if no placeholder is defined. The server does not run defer triggers. On the client, the placeholder is hydrated and the triggers become active, so the deferred content appears only after the client-side trigger fires. Readers who expect the full component in the page source will be surprised by this. If the server must render the main deferred template, use Incremental Hydration with hydrate triggers, described in the Incremental Hydration guide.
Common mistakes and how to avoid them
- Deferring above-the-fold content. Angular’s guide advises: “Avoid deferring components that are visible in the user’s viewport on initial load.” Deferring such content can cause layout shift as it pops in. Reserve space with the placeholder or leave it eager.
- Nesting blocks on the same trigger. Nested defer blocks that share a trigger can produce cascading requests. Give inner blocks different triggers.
- Silent updates for assistive technology. Screen readers may announce only the placeholder and miss content that arrives later. Wrap state changes that matter in an
aria-liveregion. - Judging behaviour in development. With HMR enabled, Angular fetches all defer dependencies eagerly, as described in NG0751. Development timing will not match production trigger behaviour, so test loading in a production build.
Measuring whether deferring helps
Angular’s guide states that deferrable views can reduce initial bundle size and often improve initial load and Core Web Vitals, particularly Largest Contentful Paint and Time to First Byte. This is a general framework statement. The official pages I consulted do not provide a numeric benchmark for any particular application, so the size of the gain for your project is unknown until you measure it.
To check the effect, follow these steps:
- Build a production bundle with
ng buildand record the initial JavaScript size before adding any defer block. - Add one
@deferblock at a time, starting with the largest non-critical component, and rebuild. - Compare the initial chunk sizes and confirm the deferred component is in its own chunk.
- Measure LCP, CLS, and interaction delay on a throttled connection, with and without the block.
- Keep the change only if the metrics improve and no visible content moves unexpectedly.
Behaviour can change between Angular releases, so check the documentation for the version your project uses before relying on a specific detail.
For the full reference, see the Deferred loading with @defer guide.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

