Programmazione

Angular: La Guida Definitiva al Lazy Loading con @defer

Sei pronto a rivoluzionare le performance della tua applicazione Angular? Con l’introduzione del blocco @defer, il lazy loading dei componenti non è mai stato così semplice e potente. Dimentica complesse configurazioni di routing o import() dinamici: oggi ti guiderò in un tutorial pratico per padroneggiare questa nuova, incredibile funzionalità.

Cos’è il Lazy Loading e Perché è Fondamentale?

Immagina di entrare in un enorme centro commerciale solo per comprare un caffè. Dovresti davvero caricare l’intera mappa del centro, con tutti i negozi e i servizi, solo per trovare il bar? Assolutamente no. Il lazy loading (o caricamento differito) applica la stessa logica alle web app: carica solo le risorse strettamente necessarie per la visualizzazione iniziale e rimanda il caricamento di tutto il resto a quando servirà davvero.

I vantaggi sono enormi:

  • Initial Load più Veloce: Il primo caricamento della pagina è fulmineo, migliorando drasticamente l’esperienza utente (UX).
  • Miglioramento dei Core Web Vitals: Un Largest Contentful Paint (LCP) più basso ti farà amare da Google.
  • Riduzione del Consumo di Risorse: Meno JavaScript da scaricare, analizzare ed eseguire significa un’app più leggera e reattiva.

Ecco a Voi @defer: Il Nuovo Supereroe di Angular

Introdotto in Angular v17, il blocco @defer è una sintassi per template che permette di dichiarare porzioni di UI da caricare in modo differito. La sua bellezza sta nella sua semplicità e potenza dichiarativa.

La sintassi base è incredibilmente intuitiva:


<p>Contenuto visibile subito.</p>

@defer {
  <app-heavy-component />
  <app-another-component />
}

In questo esempio, app-heavy-component e app-another-component (e tutte le loro dipendenze) non verranno inclusi nel bundle JavaScript iniziale. Verranno scaricati dal browser solo quando Angular lo riterrà opportuno. Ma quando, esattamente? È qui che la magia si scatena.

Trigger di @defer: Quando Caricare i Componenti?

Il vero potere di @defer risiede nella sua capacità di definire condizioni precise per avviare il caricamento. Vediamo i trigger principali.

1. on viewport – Carica Quando Diventa Visibile

Questo è il caso d’uso più comune. Il componente viene caricato non appena il suo segnaposto entra nell’area visibile dello schermo (il viewport).


@defer (on viewport) {
  <app-user-comments />
} @placeholder {
  <div class="comments-skeleton"></div>
}

Caso d’uso: Perfetto per sezioni “in fondo alla pagina” come commenti, footer complessi o gallerie di immagini.

2. on interaction – Carica all’Interazione dell’Utente

Il caricamento viene avviato quando l’utente clicca o interagisce con l’area del segnaposto.


@defer (on interaction) {
  <app-contact-form />
} @placeholder {
  <button>Carica il modulo di contatto</button>
}

Caso d’uso: Ideale per componenti interattivi come moduli, sezioni di chat o widget che non sono essenziali subito.

3. on hover – Carica al Passaggio del Mouse

Il caricamento parte quando il cursore del mouse passa sopra l’area del segnaposto.


@defer (on hover) {
  <app-mega-menu />
} @placeholder {
  <div>Menu Avanzato</div>
}

Caso d’uso: Utile per menu complessi o anteprime che richiedono il caricamento di dati significativi.

4. when – Il Trigger Condizionale

Puoi legare il caricamento a qualsiasi condizione booleana, come lo stato di un segnale o di una variabile.


// nel tuo component.ts
showCharts = signal(false);

<button (click)="showCharts.set(true)">Mostra Grafici</button>

@defer (when showCharts()) {
  <app-dashboard-charts />
}

Caso d’uso: Dashboard, pannelli di amministrazione e qualsiasi UI che dipende da una specifica azione o stato dell’applicazione.

Gestire gli Stati: @placeholder, @loading, e @error

Un’esperienza utente di qualità richiede di gestire cosa l’utente vede mentre attende. @defer offre blocchi specifici per questo.

  • @placeholder: Obbligatorio. Mostra un contenuto temporaneo prima che il trigger si attivi. È fondamentale che sia leggerissimo. Puoi specificare anche un’altezza minima per evitare sgradevoli “salti” di layout (Layout Shift).
  • @loading: Opzionale. Mostra un indicatore di caricamento (es. uno spinner) dopo che il trigger si è attivato e mentre il bundle del componente viene scaricato.
  • @error: Opzionale. Mostra un messaggio di errore se il caricamento del componente fallisce (es. per problemi di rete).

Ecco un esempio completo:


@defer (on viewport) {
  <app-photo-gallery />
} @placeholder (minimum 500px) {
  <div class="gallery-skeleton"></div>
} @loading {
  <mat-spinner></mat-spinner>
} @error {
  <p>Impossibile caricare la galleria. Riprova più tardi.</p>
}

Best Practice e Consigli da Pro

  1. Scegli il Trigger Giusto: Non usare on interaction se il componente è essenziale per la navigazione. Usa on viewport per contenuti “below the fold”.
  2. Mantieni i Placeholder Leggeri: Il blocco @placeholder non deve contenere logica complessa o componenti pesanti. L’ideale è HTML e CSS puri per creare uno “scheletro” dell’interfaccia.
  3. Evita il Layout Shift: Usa il parametro minimum nel @placeholder (es. @placeholder (minimum 200px)) per riservare lo spazio verticale che il componente reale occuperà, evitando che la pagina “salti” al suo caricamento.
  4. Prefetching Strategico: Puoi “pre-caricare” le risorse in background usando prefetch. Ad esempio, puoi avviare il download quando l’utente passa il mouse, e poi renderizzare il componente solo al click.
    
    @defer (on interaction; prefetch on hover) {
      <app-checkout-form />
    }
            
  5. Non Abusarne: Non tutto deve essere caricato in modo differito. Componenti critici e immediatamente visibili (come l’header principale) dovrebbero essere caricati normalmente.

Per altre best practice su Angular: Top 8 estensioni di Visual Studio Code per Angular.

Pro e Contro di @defer

Vantaggi (Pro) 👍Svantaggi (Contro) 👎
Semplicità Estrema: Sintassi dichiarativa e facile da capire.Nuova Sintassi: Richiede un po’ di abitudine per chi arriva da *ngIf.
Migliori Performance: Riduce drasticamente il TTI e migliora i Core Web Vitals.Potenziale Layout Shift: Se non gestito correttamente con i placeholder.
Controllo Granulare: I trigger offrono un controllo preciso sul quando e come caricare.Over-engineering: Usarlo per componenti piccolissimi potrebbe essere eccessivo.
Migliore UX: Con @loading e @error puoi gestire ogni stato del caricamento.Non è una soluzione magica per un’architettura dati lenta.

Conclusione: @defer è il Futuro

Il blocco @defer non è solo una nuova feature, è un cambio di paradigma per lo sviluppo di applicazioni Angular performanti. Rende il lazy loading accessibile, intuitivo e potente. Integrarlo nelle tue applicazioni significa offrire agli utenti un’esperienza più veloce e fluida, con un impatto positivo diretto sulla SEO e sulla soddisfazione generale.

Inizia a sperimentare oggi stesso: identifica i componenti più pesanti e meno critici della tua app e prova a caricarli con @defer. I risultati ti sorprenderanno!

Hai già scoperto cosa sono e cosa si può fare con gli Angular Signals? No?! Allora corri subito a leggere il nostro articolo sll’argomento!

Leggi di più

Antonio Marzella

Ciao, sono Antonio Marzella, un professionista del settore IT, lavoro come sviluppatore frontend in un'azienda di consulenza informatica. Negli ultimi anni, ho assunto anche il ruolo di Scrum Master, dimostrando versatilità e capacità di adattarmi a ruoli diversi all'interno del team di sviluppo. Autodidatta per natura, ho sempre avuto una passione per la tecnologia, l'informatica, l'apprendimento e l'innovazione. Determinazione, curiosità e ambizione mi hanno spinto a studiare in modo indipendente, raggiungendo risultati significativi attraverso il duro lavoro e il sacrificio.

Potrebbe interessarti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Pulsante per tornare all'inizio