I presented to you in a previous article the basics of deferrable views in Angular. Now that you know what you can do with them, let’s in the technical details to extract the performance out of them !
How do they work
Under the hood, the deferrable views are a feature of the angular compiler.
When compiling the templates, the Angular compiler extracts all dependencies used within the @defer block into a separate function and generates a number of dynamic imports to load corresponding JS chunks.
| Template | compiled |
|---|
| @defer { <my-heavy-component /> } | ```
function defer_for_block {
return [ () => import(’./my-heavy-component’) ]
}
Basically this `@defer` block results in a single dynamic import that will be executed when the trigger fires.
## Nesting blocks
When there are multiple dependencies in a `@defer` block they end-up in the same import function (except dependencies located inside of nested `@defer` blocks).
| Template | compiled |
| --- | --- |
| ```
@defer { // Block A
@if (option === 'a') {
<heavy-component-a />
} @else if (option === 'b') {
<heavy-component-b />
} @else {
@defer { // Block B
<heavy-component-c />
}
}
}
``` | ```
function defer_for_blockA {
return [
() => import('./heavy-component-a'),
() => import('./heavy-component-b')
]
}
function defer_for_blockB {
return [
() => import('./heavy-component-c')
]
}
``` |
In this scenario, we have 2 `@defer` blocks resulting in 2 generated lazy-loading functions.
When the trigger for block BlockA is fired, both chunks would be loaded, but only one of the components would be rendered. The third chunk would only be loaded, once we make it into the last `@else` block.
So, if all of the components are "heavy", you may want to consider wrapping those components into individual `@defer` blocks (similar to what we have in the last `@else` block). The same logic would apply if we replace the `@if` block with a `@switch` block.
## `@for` or `@defer` first ?
Now that we know that nesting has implications, let's compare the differences when using an `@for` block in combination with a `@defer` block.
First we need to understand the runtime implications of a `@defer` block.
At runtime, a `@defer` block's content is represented by an embedded view (as if the content was in an `<ng-template>`). Next look at 2 possibles combinations :
| `@defer` inside of `@for` | `@for` inside of `@defer` |
| --- | --- |
| ```
@for (item of items) {
@defer {
<my-heavy-component />
}
}
``` | ```
@defer {
@for (item of items) {
<my-heavy-component />
}
}
``` |
In the left example, for each item there will be an embedded view created as a part of `@for` loop and a nested embedded view created for each `@defer` block. The number of embedded views would be `items.length * 2` and the number of defer block instances would be `items.length`.
The right example would produce `items.length + 1` embedded views and a single defer block instance.
| `@defer` inside of `@for` | `@for` inside of `@defer` |
| --- | --- |
| - `items.length * 2` embedded views - `items.length` defer block instances | - `items.length` embedded views - A single defer block instance |
So for the cases above, where the contents of the `@for` loop doesn't have conditions with different "heavy" components, it would make sense to choose the right example where the `@defer` is outside of the `@for` loop.
However, if the contents of the `@for` loop has some extra logic and involves showing different "heavy" components depending on certain conditions, you may want to choose the left example where `@defer` is inside of the `@for` loop to wrap a particular component or a group of components.
Now that you know the implications of the usage:

If you have any other questions on this great new feature, feel free to reach out to me on [Twitter](https://twitter.com/Jean__Meche) !