How to implement Deferrable Views or deferred loading using @defer.

Angular 17 has been released in the beginning of November, and it has an exciting impressive and highly beneficial feature called deferred loading also known as Deferrable views.

Deferrable Views

I suppose you already know about Lazy loading, Lazy loading is a technique used in computer programming and web development to defer the loading of certain resources until they are actually needed. The idea is to delay the loading of non-essential or large resources until they are required, thereby improving the initial loading time and overall performance of an application or website.

In the previous Angular versions, we can lazy-load a part of the application using the technique via router’s loadChildren and code splitting via one-module-per-component for shared modules.

In this article I want to tell you one more technique which can help you to increase the efficiency by reducing the bundle size of the application.

The Angular team is going to take lazy-loading a step further in Angular 17. The @defer control block in Angular allows the content of the block to be loaded slowly. The dependencies of the block’s content are likewise subject to lazy loading; all of the block’s components, directives, and pipes will all be loaded slowly.

Key aspects of lazy loading in Angular 17

  • how to define a logical statement that will cause a deferred block to be rendered
  • Which trigger types are supported, and how can we specify a declarative trigger condition to trigger the rendering (for instance on hover)?
  • how to use extra @placeholder, @loading, and @error blocks to display a placeholder, a loading state, or an error state
  • how to use prefetching

@defer with a logical expression

The defer block, sometimes referred to as Deferrable views, is mostly used for slow loading material. If it’s a component, directive, or pipe if it is inserted inside a defer block, Angular will only load it in response to predefined events or conditions. Performance optimization benefits greatly from this, especially when some components aren’t immediately required or visible to the user. By default, a @defer block is triggered when the browser state becomes idle.

@defer {
 <deferedComponent/>
}

The code above is an example of how to use a basic @defer block. By default @defer will load the deferedComponent component when the browser is idle.

Dependencies inside of a @defer block must fulfill two requirements in order to be deferred:

  • Dependencies need to be standalone. Even if they are placed inside @defer blocks, non-standalone dependencies cannot be postponed and will load immediately.
  • ViewChild queries and other dependencies cannot be explicitly accessed from the same file outside of @defer blocks.

@defer can be utilized with multiple sub blocks to ensure a smooth handling of different stages in the deferred loading process. Different blocks as stated below.

@placeholder

An optional block called @placeholder specifies content that will appear before the defer block is activated. After loading is finished, the main content replaces this placeholder content. Any content, including plain HTML, components, directives, and pipes, can be used in the placeholder section; however, bear in mind that the placeholder block’s dependencies are being eagerly loaded.

The @placeholder block accepts an optional parameter to specify the minimum amount of time that this placeholder should be shown.

@defer {
  <deferedComponent />
} @placeholder (minimum 500ms) {
  <p>Placeholder content</p>
}

@loading

Displays the specified content during the loading phase of dependencies.

@defer {
  <deferedComponent />
} @loading (after 100ms; minimum 1s) {
  <img alt="loading..." src="loading.gif" />
}

@error

Displays the specified content if there’s an issue loading content’s dependencies.

@defer {
  <deferedComponent />
} @error {
  <p>Failed to load the calendar</p>
}

Leave a Reply