# Angular @defer in 2026: Declaratief Lazy Loading voor Snellere Applicaties
> Beheers Angular @defer-blokken voor declaratief lazy loading. Diepgaande analyse van triggers, prefetching, incrementele hydratie, SSR-gedrag en performancepatronen uit de praktijk.
- Published: 2026-06-14
- Updated: 2026-06-14
- Author: SharpSkill
- Tags: angular, angular-defer, lazy-loading, performance, ssr, signals, deep-dive
- Reading time: 9 min
---
Angular `@defer`-blokken bieden een oplossing voor een probleem dat routergebaseerd lazy loading nooit kon adresseren: het on-demand laden van individuele componenten, directives en pipes zonder de applicatie te herstructureren in afzonderlijke routes. Geintroduceerd in Angular 17 en gestabiliseerd in de loop van Angular 22, transformeert `@defer` wat voorheen dynamische imports, `*ngIf`-vlaggen en webpack-configuratie vereiste tot een enkel declaratief templateblok.
> **Wat @defer doet**
>
> `@defer` instrueert de Angular-compiler om ingepakte componenten af te splitsen in afzonderlijke JavaScript-chunks, die pas worden geladen wanneer een triggerconditie wordt geactiveerd. De browser downloadt minder JavaScript bij de eerste lading, wat Largest Contentful Paint (LCP) en Time to First Byte (TTFB) verbetert zonder handmatige code-splittingconfiguratie.
## Hoe @defer onder de motorkap werkt
Wanneer de Angular-compiler een `@defer`-blok tegenkomt, extraheert deze elke standalone component, directive en pipe binnenin het blok naar een afzonderlijke chunk. De hoofdbundel wordt verzonden zonder deze afhankelijkheden. Tijdens runtime evalueert Angular de triggerconditie en haalt de chunk op via een dynamische `import()`-aanroep.
Het blok ondersteunt vier subblokken die bepalen wat de gebruiker ziet tijdens de laadcyclus:
```typescript
// app.component.html
@defer (on viewport) {
} @placeholder {
} @loading (minimum 200ms) {
} @error {
Failed to load the dashboard. Please refresh.
}
```
`@placeholder` wordt gerenderd voordat de trigger wordt geactiveerd. `@loading` verschijnt terwijl de chunk wordt gedownload, met een optionele `minimum`-duur om flikkering te voorkomen. `@error` vangt netwerkfouten of chunkfouten op. De parameter `minimum` op `@loading` voorkomt een korte flits van de spinner wanneer de chunk snel vanuit de cache wordt geladen.
Een belangrijke beperking: elke afhankelijkheid binnen `@defer` moet standalone zijn. Niet-standalone componenten die in een `NgModule` zijn gedeclareerd, kunnen niet worden uitgesteld en worden ongeacht de `@defer`-wrapper eager geladen.
## Triggertypes: bepalen wanneer componenten worden geladen
Angular biedt zeven ingebouwde triggers, elk gericht op een andere laadstrategie. Meerdere triggers kunnen worden gecombineerd met puntkomma's en worden als OR-condities geevalueerd.
```typescript
// product-page.component.html
// Loads when the browser goes idle (default)
@defer {
}
// Loads when the element enters the viewport
@defer (on viewport) {
}
// Loads on click or keydown
@defer (on interaction) {
} @placeholder {
}
// Loads on mouseenter or focusin
@defer (on hover) {
}
// Loads after 3 seconds
@defer (on timer(3s)) {
}
// Loads immediately after initial render
@defer (on immediate) {
}
```
De trigger `on viewport` maakt intern gebruik van de [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API). De trigger `on idle` delegeert naar `requestIdleCallback`, waardoor het de veiligste standaardkeuze is voor content onder de vouw. De trigger `on timer` accepteert duren in milliseconden (`500ms`) of seconden (`3s`).
### De `when`-trigger voor reactieve condities
Naast event-gebaseerde triggers accepteert `when` elke booleaanse expressie, inclusief signallezingen:
```typescript
// dashboard.component.ts
export class DashboardComponent {
showAdvanced = signal(false);
}
// dashboard.component.html
@defer (when showAdvanced()) {
} @placeholder {
}
```
Het combineren van `on` en `when` is geldig. Angular behandelt deze als OR: het blok wordt geladen wanneer aan een van beide condities wordt voldaan.
## Prefetching: downloaden en weergeven ontkoppelen
Prefetching ontkoppelt het moment waarop de chunk wordt gedownload van het moment waarop het component wordt gerenderd. Dit elimineert waargenomen vertraging door het JavaScript op te halen voordat de gebruiker het activeert.
```typescript
// settings.component.html
@defer (on interaction; prefetch on idle) {
} @placeholder {
}
```
In dit patroon downloadt de browser de `account-settings`-chunk tijdens inactieve tijd. Wanneer de gebruiker klikt, wordt het component onmiddellijk gerenderd omdat de code al beschikbaar is. Prefetching accepteert dezelfde triggertypes als de hoofd-`on`-clausule.
Een veelgebruikt patroon voor dashboards: zware componenten prefetchen tijdens idle-tijd terwijl de rendering wordt uitgesteld tot het element de viewport bereikt.
```typescript
// analytics.component.html
@defer (on viewport; prefetch on idle) {
} @placeholder (minimum 100ms) {
}
```
De `minimum` op `@placeholder` voorkomt een layoutflits wanneer de gebruiker snel scrollt en het uitgestelde component vrijwel onmiddellijk wordt geladen.
## @defer en server-side rendering
Op de server rendert `@defer`-blokken standaard de `@placeholder`-inhoud. Het uitgestelde component wordt nooit server-side gerenderd. Dit gedrag is opzettelijk: het downloaden van chunks heeft alleen zin in een browsercontext.
Voor SEO-kritieke content betekent dit dat `@placeholder` betekenisvolle HTML moet bevatten, niet slechts een spinner:
```typescript
// blog-post.component.html
@defer (on viewport) {
} @placeholder {
Comments
Loading comments...
}
```
Zoekmachines indexeren de placeholder-inhoud tijdens SSR. Een beschrijvende placeholder zorgt ervoor dat de pagina semantisch compleet blijft.
## Incrementele hydratie met @defer
Angular 19 introduceerde [incrementele hydratie](https://angular.dev/guide/incremental-hydration) als developer preview, en Angular 22 stabiliseert het als een productieklare functionaliteit. Incrementele hydratie breidt `@defer` uit met een `hydrate`-trigger die bepaalt wanneer een server-gerenderd component interactief wordt op de client.
```typescript
// product-page.component.html
@defer (hydrate on viewport) {
}
@defer (hydrate on interaction) {
}
```
In tegenstelling tot standaard `@defer` rendert incrementele hydratie de volledige HTML van het component op de server. De client ontvangt complete markup maar stelt de hydratie van het component uit tot de trigger wordt geactiveerd. Het resultaat: de browser schildert de volledige pagina onmiddellijk, maar de JavaScript-uitvoering wordt uitgesteld.
Het Angular-team rapporteert consistente verbeteringen van 40-50% in LCP-scores bij het gebruik van incrementele hydratie op content-intensieve pagina's. Angular DevTools in versie 22 visualiseert hydratie-statussen (pending, hydrated, error) rechtstreeks in de componentinspector.
## Praktijkpatronen en performancestrategie
### Patroon 1: zwaar dashboard met meerdere uitgestelde panelen
```typescript
// dashboard.component.html
@defer (on viewport; prefetch on idle) {
} @placeholder {
}
@defer (on viewport; prefetch on idle) {
} @placeholder {
}
@defer (on interaction) {
} @placeholder {
}
```
Elk paneel wordt onafhankelijk geladen. Het exportpaneel blijft ongeladen totdat de gebruiker het expliciet opvraagt, waardoor een volledige chunkdownload wordt bespaard voor gebruikers die nooit exporteren.
### Patroon 2: conditioneel laden van functionaliteit met signals
```typescript
// editor.component.ts
export class EditorComponent {
user = inject(UserService).currentUser;
isPremium = computed(() => this.user()?.plan === 'premium');
}
// editor.component.html
@defer (when isPremium()) {
} @placeholder {
}
```
Gebruikers met het gratis abonnement downloaden nooit de AI-assistentchunk. De upgrade-banner fungeert zowel als placeholder als conversieprompt.
### Veelvoorkomende valkuilen vermijden
Het nesten van `@defer`-blokken met dezelfde trigger veroorzaakt gelijktijdige chunkdownloads. Spreid triggers over geneste blokken:
```typescript
// Avoid: both fire on idle simultaneously
@defer {
@defer {
}
}
// Better: outer on idle, inner on viewport
@defer (on idle) {
}
// Inside wrapper-component template:
@defer (on viewport) {
}
```
Een andere valkuil: het gebruik van `@defer` voor componenten die zich al in het kritieke renderpad bevinden. Het uitstellen van boven-de-vouw-content verhoogt de LCP omdat de browser de chunk eerst moet downloaden en uitvoeren voordat het scherm wordt geschilderd. Reserveer `@defer` voor content onder de vouw of door gebruikers geactiveerde content.
## @defer versus routergebaseerd lazy loading
Routergebaseerd lazy loading en `@defer` vullen elkaar aan. Routergebaseerd lazy loading splitst op routeniveau, waarbij volledige feature-modules worden uitgesteld. `@defer` splitst binnen een template, waarbij individuele componenten worden uitgesteld.
| Aspect | Router Lazy Loading | @defer |
|--------|-------------------|--------|
| Granulariteit | Route-niveau | Component-niveau |
| Trigger | Navigatie-event | viewport, idle, interaction, hover, timer, conditie |
| SSR-gedrag | Volledige server-rendering | Placeholder op de server |
| Standalone vereist | Nee (werkt met NgModules) | Ja (alleen standalone) |
| Prefetching | `preloadingStrategy` | `prefetch on`-clausule |
| Toepassing | Feature-modules, pagina's | Widgets, panelen, conditionele UI |
Een typische applicatie maakt gebruik van beide benaderingen: routergebaseerd lazy loading voor feature-gebieden op het hoogste niveau en `@defer` voor zware componenten binnen die gebieden.
## Sollicitatievragen over Angular @defer
Technische sollicitatiegesprekken behandelen steeds vaker `@defer` omdat het centraal staat in de performancestrategie van Angular. Hieronder volgen patronen die regelmatig voorkomen in [Angular-sollicitatievragen](/technologies/angular/interview-questions/standalone-components).
**Vraag: Wat gebeurt er als een niet-standalone component in @defer wordt geplaatst?**
Het component wordt ongeacht het `@defer`-blok eager geladen. De Angular-compiler kan componenten die in een NgModule zijn gedeclareerd niet in afzonderlijke chunks extraheren. Er wordt geen foutmelding gegenereerd, maar de optimalisatie faalt stilzwijgend.
**Vraag: Hoe gedraagt @defer zich tijdens SSR?**
De server rendert de `@placeholder`-inhoud. Het uitgestelde component wordt nooit server-side gerenderd. Hydratie vindt plaats op de client wanneer de trigger wordt geactiveerd (of via `hydrate on` voor incrementele hydratie).
**Vraag: Kan @defer worden gebruikt met OnPush change detection?**
Ja. `@defer` is een functionaliteit op templateniveau en werkt met elke change-detectiestrategie. Het uitgestelde component volgt na het laden zijn eigen change-detectieconfiguratie.
**Vraag: Wat is het verschil tussen `on idle` en `on immediate`?**
`on idle` wacht tot de browser al het lopende werk heeft afgerond via `requestIdleCallback`. `on immediate` triggert direct nadat Angular de initiele rendercyclus heeft voltooid, zonder te wachten op een inactieve status. `on immediate` is nuttig voor componenten die snel moeten laden maar de eerste paint niet mogen blokkeren.
Voor een breder scala aan Angular-sollicitatievoorbereiding, zie de module [Angular change detection](/technologies/angular/interview-questions/change-detection) en de module [Angular signals](/technologies/angular/interview-questions/angular-signals).
## Conclusie
- `@defer` splitst standalone componenten af in afzonderlijke chunks die on-demand worden geladen, waardoor de initiele bundelgrootte wordt verkleind zonder routeherstructurering
- Zeven triggertypes (`idle`, `viewport`, `interaction`, `hover`, `timer`, `immediate`, `when`) dekken elke laadstrategie van passief tot gebruikersgestuurd
- `prefetch on` ontkoppelt het downloaden van chunks van het renderen van componenten, waardoor waargenomen vertraging bij door gebruikers geactiveerde componenten wordt geelimineerd
- Incrementele hydratie (`hydrate on`) rendert volledige HTML op de server terwijl JavaScript-uitvoering naar de client wordt uitgesteld, met 40-50% verbetering in LCP op content-intensieve pagina's
- `@placeholder`-inhoud wordt gerenderd tijdens SSR en moet semantisch betekenisvol zijn voor SEO
- `@defer` vult routergebaseerd lazy loading aan: routes voor splitsing op functieniveau, `@defer` voor splitsing op componentniveau binnen templates
- Niet-standalone componenten kunnen niet worden uitgesteld en worden stilzwijgend eager geladen
---
Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack.
HTML version of this page: https://sharpskill.dev/nl/blog/angular/angular-defer-loading-declarative-lazy-loading-guide