Skip to the solution
MediumFrontend9 min read

How does the @defer block work and what triggers are available?

563 views

The problem

Question presented to candidate: "Walk me through what happens when Angular meets a @defer block, then list the triggers you can use, and pick the right one for: a below-the-fold reviews section, a settings panel behind a button, and a chat widget that should load once the page is quiet."

What a strong answer should cover:

  • The sequence: placeholder rendered, trigger fires, dependency function loads code, content swaps in (or @error).
  • on triggers: idle (default), immediate, timer(...), viewport, interaction, hover; targets via template references.
  • when expr: loads when truthy, one-shot.
  • Multiple triggers are OR-ed; prefetch and hydrate variants are separate families.
  • Sensible choices: viewport for reviews, interaction/hover (+ prefetch on hover) for the panel, idle or timer for the chat widget.
  • Constraints: triggers without a target need a @placeholder; viewport needs IntersectionObserver.

Clarifying questions expected:

  • "Is the page server-rendered? Then hydrate triggers may matter too."

Code / implementation expected: Yes — a template with several @defer blocks using different triggers.

  • defer
  • performance
  • lazy-loading

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

9 min read · 9 sections

Read the code

AngularSix @defer blocks, one per trigger, driven by a script
import { Component, signal } from "@angular/core";

@Component({
  selector: "app-panel",
  template: `<span>[{{ name }} loaded]</span>`,
  inputs: ["name"],
})
export class PanelComponent {
  name = "";
}

@Component({
  selector: "app-root",
  imports: [PanelComponent],
  template: `
    <h3>Defer triggers</h3>

    @defer (on immediate) { <app-panel name="immediate" /> } @placeholder { <span>[immediate waiting]</span> }

    @defer (on idle) { <app-panel name="idle" /> } @placeholder { <span>[idle waiting]</span> }

    @defer (on timer(300ms)) { <app-panel name="timer" /> } @placeholder { <span>[timer waiting]</span> }

    @defer (on interaction) { <app-panel name="interaction" /> } @placeholder { <button id="open">[click me]</button> }

    @defer (on hover(hoverTarget)) { <app-panel name="hover" /> } @placeholder { <span>[hover waiting]</span> }
    <em #hoverTarget id="hover">hover here</em>

    @defer (when ready()) { <app-panel name="when" /> } @placeholder { <span>[when waiting]</span> }
    <button id="ready" (click)="ready.set(true)">set ready</button>
  `,
})
export class AppComponent {
  ready = signal(false);
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 47 of 121 in Angular

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Angular questions
Up nextMedium

What is the purpose of updateOn in Reactive Forms?

Continue