The unit tests were also adjusted to consider the component dependencies in the TestBed definition, and you can find the test code in the GitHub repository of this chapter.
The last adjustment must be made in the DiaryModule module:
@NgModule({
declarations: [
NewEntryFormTemplateComponent,
NewEntryFormReactiveComponent,
],
imports: [
CommonModule,
DiaryRoutingModule,
RouterModule,
FormsModule,
ReactiveFormsModule,
],
})
export class DiaryModule {}
As we will dynamically load the components that were converted to standalone, we have to remove these components from the declarations attribute of the module.
After this preparation, we can use the defer command in the diary.component.html file:
@defer {
<app-list-entries
[exerciseList]=”exerciseList”
(deleteEvent)=”deleteItem($event)”
(editEvent)=”editEntry($event)”
/>
}
To use the defer command, we must create a block that includes the components that we want to lazy load.
If we run our application and analyze the Networks tab, we will notice that specific bundles are loaded when the screen is rendered:

Figure 12.1 – Lazy-loaded bundle
We can see that the effect is similar to the lazy loading of a route module, but defer has other interesting options. Let’s see this in practice by changing our code:
@defer (on hover(trigger))
{
<app-list-entries
[exerciseList]=”exerciseList”
(deleteEvent)=”deleteItem($event)”
(editEvent)=”editEntry($event)”
/>
}
<button
#trigger
class=”rounded bg-blue-500 px-4 py-2 font-bold text-white hover:bg-blue-700″
(click)=”newList()”
>
Server Sync
</button>
With the on hover(trigger) condition, the list is loaded when we hover over the Server Sync button. This is just an example; the defer command opens up a range of opportunities for fine-tuning the user experience. The defer command has the following conditions:
- on immediate: The component will be loaded the moment the screen is rendered.
- on idle: The component will be loaded on the first call to the browser requestIdleCallback API. This API allows non-blocking processing in the browser and is the default behavior of the defer command.
- on hover(target): We can define another interface component and loading will occur when the user hovers over this component.
- on timer(time): Allows us to define in milliseconds when the component will be loaded after the interface is rendered.
- on viewport(target): When the target component is in the browser’s viewport, the child components will be loaded. This behavior is ideal for loading a component that is located after the user has scrolled to the end of the page.
- on interaction(target): It has a similar behavior to on hover, but it will be triggered by some interaction, such as a click.
- when (condition): Allows us to control the loading of the component imperatively, through a Boolean attribute, or a function that returns a Boolean.
Complementing the defer command, we have other commands that we can use. Returning to our code, we will change it as follows:
@defer {
<app-list-entries
[exerciseList]=”exerciseList”
(deleteEvent)=”deleteItem($event)”
(editEvent)=”editEntry($event)”
/>
} @loading {
<div>Loading</div>
} @placeholder {
<div>PlaceHolder</div>
} @error {
<div>Error</div>
}
These complementary commands have the following functions:
- @loading: Presents the content of the block while the components of the defer block are loaded
- @placeholder: Displays the content of the block, while the components of the defer block do not start loading, for example, if the user does not hover over the given target
- @error: Displays the content of the block if an error occurs when loading the components of the defer block
There are many possibilities that we have with this defer command in our templates, and we should explore them to improve our users’ experience. But note that we should not lazy load all the components of a screen. We need to use the defer command on large components or components that are not essential for the page we are building.
In the next section, we will explore how to improve the experience of transitions between routes in our application.
No Responses