Deferrable views in Angular | Aulab
TECH SUMMER LAB 🚀 Open Month
| 6 lezioni gratuite per orientarti al meglio e iniziare a costruire il tuo futuro digitale! Iscriviti gratis

GUIDE PER ASPIRANTI PROGRAMMATORI

Deferrable views in Angular

Abbiamo già abbondantemente elencato le ragioni e i vantaggi dietro alle moderne web app e alla navigazione frontend. Tuttavia, poiché una caratteristica delle SPA è che tutte le viste e la loro logica fanno parte del pacchetto servito come pagina web al browser; questo, in genere, comporta maggiori tempi per il caricamento iniziale rispetto ad…

Lezione 16 / 17
Enza Neri
Immagine di copertina

Vuoi avviare una nuova carriera o fare un upgrade?

Trova il corso Digital & Tech più adatto a te nel nostro catalogo!

Abbiamo già abbondantemente elencato le ragioni e i vantaggi dietro alle moderne web app e alla navigazione frontend. Tuttavia, poiché una caratteristica delle SPA è che tutte le viste e la loro logica fanno parte del pacchetto servito come pagina web al browser; questo, in genere, comporta maggiori tempi per il caricamento iniziale rispetto ad una web app classica, con le viste renderizzate una ad una lato server.

Le deferrable views (viste differibili), o più semplicemente blocchi @defer, sono uno strumento di Angular che rende possibile differire il caricamento di dipendenze come componenti, pipes o direttive, in modo che non pesino sul caricamento iniziale della nostra web app.

In pratica, con questo strumento, Angular ci consente di rimandare il caricamento di elementi non necessari immediatamente, eventualmente mostrando dei segnaposti durante il caricamento.


Un blocco @defer si dichiara in un template HTML esattamente allo stesso modo dei blocchi di control flow già visti, e può essere associato ad altri sotto-blocchi per regolarne il comportamento.

Un esempio basilare di vista differibile ha questo aspetto:

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

In questo esempio, il componente app-heavy-component viene caricato appena il browser va in stato idle, in seguito al caricamento iniziale dell’app. Come vedremo a breve, è possibile impostare diversi criteri e condizioni per il differimento.

Se lasciamo tutto così, in attesa che il caricamento del componente sia ultimato, Angular non mostrerà nulla; va da sé che questa non è la UX più desiderabile. Possiamo fare in modo che Angular rappresenti sin da subito un segnaposto, e poi lo sostituisca con la vista differita quando questa è pronta:

@defer {
  <app-heavy-component />
} @placeholder {
  <p>Placeholder content</p>
}

Generalmente, ogni blocco @defer è associato a un sottoblocco @placeholder.
Per evitare sfarfallii dovuti al repentino cambio di schermata, è possibile anche introdurre un parametro minimum, che rappresenta il tempo minimo dopo il quale il blocco @placeholder può essere sostituito dal contenuto effettivo:

@defer {
  <app-heavy-component />
} @placeholder (minimum 600ms) {
  <p>Placeholder content</p>
}

In questo caso, il placeholder verrà mostrato per un minimo di 600 millisecondi; questo tempo può anche essere espresso in secondi (in questo caso: 0.6s).

Come abbiamo anticipato, il differimento della vista è soggetto a criteri e condizioni. Questo significa che potrebbe passare un tempo significativo tra il caricamento iniziale della web app e l’inizio del caricamento del blocco @defer.


Per questo, oltre a @placeholder, è possibile specificare anche un blocco @loading, specificamente dedicato all’effettivo caricamento della vista. Oltre a minimum, @loading ha un parametro after per regolare dopo quanto tempo si ritiene necessario dare all’utente un riscontro del caricamento in corso:

@defer {
  <app-heavy-component />
} @loading (after 100ms; minimum 1s) {
  <app-spinner />
}

Solitamente, come in questo esempio, il blocco @loading viene usato per mostrare uno spinner o qualcosa di analogo. Poiché il blocco @defer introduce un caricamento secondario, esiste anche l’eventualità che questo non vada a buon fine; per questo, un altro sottoblocco importante è @error, che ci consente di dare un riscontro all’utente nel caso in cui il caricamento del blocco @defer fallisca:

@defer {
  <app-heavy-component />
} @error {
  <p>Failed to load</p>
}

Vediamo, infine, come possiamo modificare l’innesco del caricamento di un blocco @defer.

Abbiamo detto che di default una deferrable view viene caricata nel momento in cui il browser termina il caricamento iniziale della web app; questo trigger è chiamato on idle.
Oltre a on idle, è possibile selezionare uno dei seguenti trigger:

  • on immediate: il caricamento parte non appena la web app viene caricata, cioè prima ancora di on idle;
  • on timer: il caricamento parte dopo un tempo prefissato espresso in millisecondi o secondi, ad esempio: @defer (on timer(100ms));
  • on viewport: il caricamento viene innescato dall’ingresso del blocco nella parte visibile della finestra del browser; questo trigger è molto utile nel caso in cui abbiamo una pagina molto lunga e vogliamo caricare i componenti man mano che l’utente scorre la pagina;
  • on interaction: il caricamento è innescato dall’interazione dell’utente con il placeholder, oppure opzionalmente con un altro elemento del template, referenziato tramite una template variable: <button #trigger>Load</button> … @defer (on interaction(trigger));
  • on hover: il caricamento è innescato dal passaggio del mouse sul placeholder, o anche qui, su un altro elemento trigger, esattamente come per on interaction.

La combinazione di diversi trigger è supportata; ad esempio, @defer (on viewport; on timer(5s)) consente di attendere l’ingresso del componente nella finestra oppure 5 secondi. Il primo trigger che si verifica, innesca il caricamento.

Oltre ai trigger, un blocco @defer può essere condizionato da un’espressione, al pari di un blocco @if, usando la parola chiave when al posto di on. In questo caso, la condizione si comporta come un trigger nel momento in cui passa da essere falsy a truthy; il caricamento non viene annullato o riportato al placeholder se questa torna ad essere falsy.

Anche le when conditions possono essere combinate insieme ai normali trigger e l’operazione booleana tra espressioni e trigger è sempre un oppure logico, vale a dire che la prima condizione che si verifica causa il caricamento.

Prima di proseguire, vediamo un’ultima ottimizzazione che è possibile operare sulle deferrable views: il prefetching. Questa operazione consiste essenzialmente nel caricare in background un defer block senza mostrarne il contenuto fino a quando non scatta un trigger effettivo.

Anche il prefetching è soggetto a trigger e condizioni con le stesse dinamiche già viste:

@defer (on interaction(trigger); prefetch on idle) {
  <app-heavy-component />
}

In questo esempio, il nostro app-heavy-component viene renderizzato solo quando l’utente interagisce con il trigger, ma in realtà nel momento in cui viene renderizzato è già stato scaricato dalla rete, poiché il prefetching è stato innescato on idle.

Hai bisogno di informazioni? 🙋🏻‍♂️

Parliamone! Scrivici su Whatsapp e risponderemo a tutte le tue domande per capire quale dei nostri corsi è il più adatto alle tue esigenze.

Oppure chiamaci al 800 128 626