Introduction
Deferrable views is a new feature in Angular 18 that allows you to defer the loading of a component until it is needed. This can help improve the performance of your application by reducing the initial bundle size.
How to use deferrable views
Load when browser is idle
Wrap your component with @defer {}
to make it deferrable. In the following example, the app-product-detail
component will be loaded only when the Browser is idle.
1 | { |
Load when component enter the viewport
You can also specify a condition for when the component should be loaded. In the following example, the app-product-detail
component will be loaded when it enters the viewport.
Placeholder
Note that, defer on viewport must be used in conjunction with @placeholder directive. When component is out of viewport, the placeholder will be rendered.
1 | (on viewport) { |
To test this, you can add a long div
element before the app-product-detail
component to make it out of the viewport.
Loading section.
You’d better add a section to show the loading state of the component.
1 | (on viewport) { |
To test the loading view, you can set the slow 3G network in the browser dev tools/network tab.
Error section
You can also specify an error section to show when the component fails to load.
1 | (on viewport) { |
This is not easy to test, not found a method yet.
Minium render time for placeholder and loading section.
To avoid flickering, you can specify a minimum render time for the placeholder and loading section. In the following example, the placeholder will be rendered for at least 200ms before the component is loaded, and the loading section will be rendered for at least 500ms.
Note that at least
doesn’t mean exactly
, for example, if the component didn’t load in 500ms, the loading section will keep showing until the component is loaded.
1 | (on viewport) { |
Trigger conditions
Angular provides several trigger conditions for deferrable views. You can use the following conditions to specify when the component should be loaded.
Trigger | Description |
---|---|
idle | Triggers when the browser is idle. |
viewport | Triggers when specified content enters the viewport |
interaction | Triggers when the user interacts with specified element |
hover | Triggers when the mouse hovers over specified area |
immediate | Triggers immediately after non-deferred content has finished rendering |
timer | Triggers after a specific duration |
idle
This is the default option, the component will be loaded when the browser is idle.
1 | () { |
viewport
The component will be loaded when the specified content enters the viewport. If you didn’t specify the content, the component will be loaded when itself enters the viewport.
1 | (on viewport) { |
You can also load the component when a specific element enters the viewport. In the following example, the app-product-detail
component will be loaded when the greeting
element enters the viewport.
1 | <div #greeting>Hello!</div> |
interaction
The interaction
trigger loads the deferred content when user interacts withe the specific element through click
or keydown
event.
By default, the placeholder acts as the interaction element. Placeholders used this way must have a single root element.
1 | (on interaction) { |
You can also specify a different element for the interaction trigger. In the following example, the app-product-detail
component will be loaded when the greeting
element is clicked.
1 | <div #greeting>Hello!</div> |
hover
Same as interaction
, you can just replace interaction
with hover
in the above examples.
immediate
This is different than idle
, the component will be loaded immediately after the non-deferred content has finished rendering.
1 | (on immediate) { |
timer
The timer
trigger loads the deferred content after a specific duration. You can specify the duration in milliseconds or seconds.
1 | timer(500ms)) { (on |
when
The when
trigger accepts a custom conditional expression and loads the deferred content when the condition becomes true. You can control the condition
in our component class.
1 | (when condition) { |
This is a one-time operation– the @defer block does not revert back to the placeholder if the condition changes to a falsy value after becoming truthy.
Conclusion
Conditions for deferrable views
- Must be standalone.
- Must not references outside of the
@defer
block in the same template file.
How it works
- Angular use dynamic import to load the deferrable views.
- The component loaded in @defer was bundled in a separated chunk.