October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

Deferred loading with @defer in Angular: Triggers, Placeholders, and SSR

Angular's @defer block splits eligible standalone dependencies into separate chunks and loads them on a trigger. Here is how triggers, placeholder states, prefetching, and SSR behave, and where deferring can hurt.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The @defer block lets you move eligible parts of a template into separate JavaScript chunks and load them later, when a trigger fires or a condition becomes true. You add it directly in a component template, choose when it should load, and optionally supply placeholder, loading, and error states. Whether it actually speeds up your application depends on what you defer and when that content is needed, so treat the syntax as a starting point and measure the result.

This guide reflects Angular’s official deferred-loading documentation as checked in October 2026. Details can change between releases, so confirm the behavior against the documentation for the Angular version your project uses.

As an Amazon Associate I earn from qualifying purchases.

A minimal @defer block

The simplest form wraps the component you want to defer:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
@defer {
  <app-large-chart />
}

With no trigger, Angular waits for the browser to become idle before it loads the chunk and renders the content. A placeholder is optional. If you supply one, it is shown before the trigger fires and is replaced once the deferred imports resolve.

What @defer can and cannot split

The @defer block works on the view dependencies it contains: components, directives, pipes, and the component CSS associated with them. The Angular compiler emits dynamic imports for these dependencies, which is what produces the separate chunks.

Eligibility is narrower than that list suggests. A dependency can be deferred only when it is standalone. Three conditions keep a dependency eagerly loaded, meaning it ends up in the initial bundle regardless of the block:

  • The dependency is not standalone. Non-standalone dependencies are always loaded eagerly.
  • The same file references the dependency outside a defer block, for example by using it in a template or importing it in a way that still uses it directly.
  • The dependency is matched by a ViewChild query.

If an eligible standalone component depends on other components, those transitive dependencies can still be declared in an NgModule and take part in the deferred load. Angular does not guarantee the order in which the generated dynamic imports resolve, so do not write code that depends on one chunk arriving before another.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choosing a trigger

The on clause decides when the chunk is requested and the content renders. Multiple triggers combine as OR conditions, so the block loads as soon as any one of them fires.

Trigger Loads when Typical use
on idle (default) The browser reports idle time Non-urgent content with no visibility or interaction requirement
on viewport The placeholder enters the viewport Content below the fold, such as comments or related items
on interaction The user interacts with the placeholder Features opened by a deliberate action, such as a tab or dialog
on hover The pointer hovers over the placeholder Pointer-driven previews where hover reflects likely intent
on immediate Right after the block is created Splitting code out of the initial bundle without waiting for a user signal
on timer(duration) After the given delay, such as 500ms or 2s Content that should appear after a fixed interval
when expression The expression first evaluates to a truthy value Application state, such as a feature flag or a loaded user object

A when condition is one-way. Once it has been truthy and the content has loaded, the block does not return to the placeholder if the expression later becomes false.

Example: viewport trigger with all states

@defer (on viewport) {
  <app-reviews />
} @placeholder (minimum 500ms) {
  <div class="reviews-skeleton" aria-hidden="true"></div>
} @loading (after 100ms; minimum 1s) {
  <p>Loading reviews…</p>
} @error {
  <p>Reviews are unavailable right now.</p>
}

The placeholder block takes a minimum duration, which keeps it on screen long enough to avoid a flash when the real content replaces it almost immediately. The loading block takes an after delay, so the indicator appears only if loading is slow, and a minimum so that once shown it stays visible long enough to be read. Durations are written with units such as ms or s.

Placeholder, loading, and error states

The three secondary blocks shape what the user sees while the chunk is pending or after it fails:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Placeholder is shown before the trigger fires and until the deferred content is ready. Keep it close in size to the real content to limit layout shift.
  • Loading is shown while the deferred dependencies are being fetched. Use it for slow loads only, not for every request.
  • Error is shown if the deferred dependencies fail to load. Give it a clear, lightweight message rather than a heavy fallback.

These blocks are not deferred themselves. Their dependencies are loaded eagerly, so an elaborate spinner or a large fallback component adds to the initial bundle. Angular documents the chunk-load failure case as NG0750: @defer dependencies failed to load; plan an error block for it, because a network failure otherwise leaves the user with no explanation.

Prefetching before the trigger

Prefetching is configured separately from rendering. A prefetch on clause or a prefetch when condition fetches the deferred code earlier, so the chunk is ready when the render trigger fires. Prefetching reduces perceived waiting, but it moves network work earlier, which can compete with more important requests. Use it for content the user is likely to need soon, and leave it out for content that may never be shown.

Server-side rendering and hydration

By default, server rendering outputs the placeholder, or nothing if no placeholder is defined. The server does not evaluate the defer triggers. In the browser, Angular hydrates the placeholder and then activates the triggers.

This means the HTML delivered by the server may not contain the deferred content you expect to see in the page source. If the server should render the main deferred template, Angular’s Incremental Hydration guide describes hydrate triggers, which control when deferred content is hydrated on the client. Choose between the two based on whether the content must appear in the initial HTML for indexing or first paint, or whether it can wait for the browser.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Accessibility and layout cautions

Deferring is not free of user-facing risk. Three cautions from Angular’s guidance apply to most applications:

  • Layout shift. Do not defer content that is visible in the initial viewport. Angular’s guide states: “Avoid deferring components that are visible in the user’s viewport on initial load.” Deferring such content can increase cumulative layout shift as it pops in.
  • Cascading requests. Nested defer blocks that use the same trigger can fire one after another, producing a chain of requests. Use different triggers for inner and outer blocks where possible.
  • Screen readers. A screen reader may announce only the placeholder and miss later content changes. Wrap the state changes in an aria-live region so that the arrival of new content is announced.

Measuring whether deferring helps

Angular’s guide says deferrable views reduce the initial bundle size and often improve initial load and Core Web Vitals, particularly Largest Contentful Paint (LCP) and Time to First Byte (TTFB). That is a general statement about the framework, not a guarantee for your application. The official documentation does not publish a numeric benchmark, so the size of the gain has to be measured.

  1. Run a production build with ng build before and after adding the block, and compare the emitted chunk files and the size of the initial bundle.
  2. Measure the deployed build, not the development server, using your normal field or lab tooling for LCP and TTFB.
  3. Check that the content you deferred is not needed for the first screen. If it is, the change may hurt the metrics it was meant to improve.
  4. Verify the placeholder, loading, and error states by throttling the network and blocking the chunk request.

Development behavior with HMR

When hot module replacement is enabled, Angular fetches all defer dependencies eagerly. This means that during development, the content may load before its trigger fires, so behavior can differ from production. Angular documents this in NG0751: @defer behavior when HMR is enabled. Test trigger behavior on a production build or with HMR turned off.

Practical checklist

  • Confirm each deferred dependency is standalone and is not used directly elsewhere in the same file or matched by a ViewChild query.
  • Choose the trigger from the user’s likely need: viewport for below-the-fold content, interaction for deliberate actions, and when for application state.
  • Keep placeholders close in size to the final content, and add an error block to every deferred section that depends on network data.
  • Use prefetch only for content the user is likely to reach soon.
  • Check the server-rendered HTML if the content must be present before hydration, and use incremental hydration if it should be rendered on the server.
  • Measure production builds before and after the change.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.