typescript 36 lines · 8 steps

Deferred chart loading with @defer in Angular

A standalone dashboard component lazy-loads a heavy chart when it scrolls into view, with skeleton, loading, and error fallbacks.

Explained by highlit
1import { Component, signal } from '@angular/core';
2import { CommonModule } from '@angular/common';
3import { RevenueChartComponent } from './revenue-chart.component';
4import { ReportService, RevenueReport } from './report.service';
5 
6@Component({
7 selector: 'app-dashboard',
8 standalone: true,
9 imports: [CommonModule, RevenueChartComponent],
10 template: `
11 <section class="dashboard">
12 <header>
13 <h1>Quarterly Revenue</h1>
14 <button (click)="refresh()">Refresh</button>
15 </header>
16 
17 @defer (on viewport; prefetch on idle) {
18 <app-revenue-chart [report]="report()" />
19 } @placeholder (minimum 300ms) {
20 <div class="chart-skeleton" aria-hidden="true"></div>
21 } @loading (after 150ms; minimum 400ms) {
22 <div class="chart-loading">Rendering chart…</div>
23 } @error {
24 <p class="chart-error">Unable to load the revenue chart.</p>
25 }
26 </section>
27 `,
28})
29export class DashboardComponent {
30 private readonly reports = inject(ReportService);
31 readonly report = signal<RevenueReport>(this.reports.snapshot());
32 
33 refresh(): void {
34 this.reports.load().subscribe((data) => this.report.set(data));
35 }
36}
01 / 01
STEP 01

Walkthrough

Space play ←→ step click any line
Three takeaways
  1. 1@defer lets you defer a component's download and render until a real trigger fires, keeping the initial bundle lean.
  2. 2Placeholder, loading, and error blocks with timing hints prevent flicker and give users honest feedback during async work.
  3. 3Signals turn plain state into reactive template bindings that re-render automatically when set.

Related explainers

typescript
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
import localeFrExtra from '@angular/common/locales/extra/fr';
import localeDe from '@angular/common/locales/de';

Locale-aware bootstrapping in Angular

i18n localization dependency-injection
Intermediate 8 steps
typescript
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import * as Joi from 'joi';
 

Validating env config at boot in NestJS

configuration schema-validation environment-variables
Intermediate 8 steps
java
@Component
@Converter
public class EncryptedStringConverter implements AttributeConverter<String, String> {
 

Transparent column encryption in Spring & JPA

encryption aes-gcm jpa-converter
Advanced 10 steps
typescript
import { Inject, Injectable, Logger } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
import { InjectRepository } from '@nestjs/typeorm';

A cache-aside country lookup in NestJS

cache-aside dependency-injection batch-lookup
Intermediate 8 steps
java
package com.acme.billing.config;
 
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;

Feature-flagged beans with Spring @ConditionalOnProperty

feature-flags conditional-beans strategy-pattern
Intermediate 5 steps
typescript
import { Injectable, effect, signal, computed } from '@angular/core';
 
interface Preferences {
  theme: 'light' | 'dark';

A signal-based preferences store in Angular

signals state-management persistence
Intermediate 7 steps

Share this explainer

Here's the card — post it anywhere.

Deferred chart loading with @defer in Angular — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code