Vincenzo Saccotelli • 2024-02-09
Esplora le innovazioni di Angular 17, dal potenziamento del flusso di controllo integrato alla rivoluzione del Server-Side Rendering. Angular 17 promette un'esperienza di sviluppo senza precedenti. Scopri di più, continua a leggere!
Indice:
Con il suo recente 13° anniversario, Angular guarda al futuro con il rilascio della versione 17. Il team di Google ha messo in luce un'ottimizzazione mirata, riducendo le dimensioni del bundle per un'esperienza di sviluppo più efficiente. Il nuovo flusso di controllo, dichiarativo e intuitivo, insieme all'adozione generalizzata dei Signals, promette un salto di qualità nelle prestazioni.
Angular 17 segna una nuova era, combinando un approccio moderno, un logo rinnovato e una documentazione all'avanguardia.
Un nuovo capitolo eccitante nell'evoluzione dello sviluppo front-end.
Angular ha anche effettuato un rebranding del suo logo, sin dagli albori del framework non era mai stato cambiato. Il nuovo logo Angular, realizzato da Google, presenta un design più moderno e colorato che rappresenta l'evoluzione di Angular e l'inizio di una nuova stagione del framework. Questo cambio lo ritroviamo anche nella documentazione.
Nuova veste per Angular v17
Fonte: Angular.Love
Oltre al logo, anche la documentazione, in versione beta, ha una nuova sede (angular.dev). Orientata al futuro, questa piattaforma offre non solo nuove guide e contenuti migliorati ma anche un percorso di apprendimento interattivo pensato per assistere gli sviluppatori del futuro nello studio di questo framework.
Grazie alla nuova documentazione, ora si ha la possibilità di utilizzare tutta la potenza di Angular CLI in qualsiasi web moderno, grazie a WebContainers.
Impor WebContainers Angular 17 Fonte: Angular.dev
Il team di Angular ha mirato a rendere l’esperienza di sviluppo molto più dichiarativa attraverso una nuova sintassi. Questa, offre potenti funzionalità con API semplificate, avvicinandosi molto di più al mondo JavaScript per la gestione del flusso di controllo integrato nei componenti, per il lazy loading e altro ancora.
Per chi conosce Angular già da qualche tempo, è abituato all’utilizzo di direttive strutturali per il controllo condizionale, i cicli e i cases.
Fino alle versioni 16 *ngIf, *ngFor, *ngSwitch sono stati i protagonisti dei file HTML nei componenti Angular.
Siamo abituati a vedere una situazione del genere:
Direttiva *ngIf Angular 16
Adesso traduciamo il codice della prima immagine in Angular 17:
Direttiva @if Angular 17
Con @if, il codice risulta molto più pulito e leggibile, soprattutto per chi proviene dal mondo JavaScript. Inoltre, poter usufruire di @else ci dà un enorme vantaggio in termini di scrittura, non essendo più costretti all’utilizzo di ng-template, che a volte, in grosse applicazioni, può creare confusione all’interno dei file HTML.
Il potere dichiarativo della nuova sintassi lo si può notare ancor di più nel caso @switch; facciamo un esempio in cui dobbiamo gestire diversi componenti in base al livello di accesso dell’utente:
Direttiva *ngSwitch Angular 16
Direttiva @switch Angular 17
Per chi ha familiarità col mondo JavaScript, queste linee di codice gli risulteranno molto familiari.
Avere la possibilità di utilizzare degli statements facilmente riconoscibili dai dev, riduce sicuramente i tempi di sviluppo e apprendimento, ma crea anche una maggiore coerenza nei componenti.
Inoltre, c’è da dire che @if, @for e @switch, diversamente da *ngIf, *ngFor e *ngSwitch, non hanno bisogno di essere importati in modo esplicito nei componenti standalone, ma sono direttamente utilizzabili in tutti i template.
Analizziamo adesso il ciclo for integrato, facendo sempre una differenza tra la versione 17 di Angular e le sue precedenti:
Direttiva *ngSwitch Angular 16
Direttiva @switch Angular 17
Notiamo anche qui una somiglianza al ciclo forOf presente in JS. In @for diventa obbligatorio l’inserimento di track che ci permette di avere prestazioni migliori.
Ancora, è stata aggiunta la possibiltà di gestire un array vuoto con @empty, che rimane comunque un blocco opzionale.
@defer scrive il futuro del lazy loading in Angular!
Con l’inserimento della struttura a blocchi, il team Angular ha sviluppato un nuovo e potente meccanismo per rendere le applicazioni più veloci. L’esperienza di sviluppo per i developer passa a un livello superiore, avendo la possibilità di sfruttare il potere dichiarativo della nuova sintassi.
Supponendo di voler gestire una lista di commenti sotto a un post; con @defer, possiamo dire ad Angular di caricarla in lazy con tutte le sue dipendenze in una sola riga:
Lazy loading @defer Angular 17
Tutto questo a noi risulta semplice con questa struttura, ma sotto il cofano Angular fa tantissimo lavoro, generando importazioni dinamiche e gestendo il processo di caricamento lento e cambiamento di stati.
La rivoluzione di @defer: Trigger e Blocchi in Angular 17
Con @defer, Angular ci dà anche la possibilità di utilizzare i trigger e dei blocchi aggiuntivi per la gestione del placeholder, loading ed error.
Quando un blocco @defer viene attivato (triggerato per i più esperti xD), verrà sostituito il placeholder con la vista lazy che abbiamo dichiarato. Esistono due opzioni di configurazione nel momento in cui avviene la sostituzione, e sono: on e when.
Qui di sotto abbiamo un esempio, con on, di come apparirebbe il codice nel caso in cui volessimo far vedere all’utente una lista di commenti solo a un determinato viewport del device di utilizzo:
Lazy loading @defer Angular 17
Il team Angular ha svolto un lavoro significativo per permettere il caricamento lento di un elemento del DOM, a un determinato viewport, sfruttando IntersectionObserver API. Questa API consente di monitorare quando un elemento entra o esce dall'area visibile della pagina web. Vi invito ad approfondirlo rendendola sfruttabile come trigger.
Ecco, alcuni trigger che potrai utilizzare con on per il lazy loading:
Come anticipato, @defer ci dà la possibilità di utilizzare altri blocchi per una gestione più completa, ne avremo principalmente quattro: @defer, @loading, @error e @placeholder. Anche qui il potere della sintassi fa da padrone, ed è subito intuibile il ruolo di ogni blocco.
Inizialmente, Angular mostrerà @placeholder, nel momento in cui ci sarà il viewport corretto, @placeholder verrà sostituito da @loading e se tutto va bene e non ci sono errori nel caricamento, il tutto lascerà posto al blocco @defer; in caso contrario, verrà mostrato il blocco @error.
Lazy loading @defer Angular 17
Con @defer è possibile anche utilizzare when, che diversamente da on, farà attivare il blocco tramite un’espressione che restituisce un valore booleano. Quindi solo se la condizione è vera il caricamento lento avviene, come nel seguente esempio:
@defer, condizione when Angular 17
On e when possono essere usati anche in contemporanea, ma il blocco @defer verrà visualizzato solo se una delle due condizioni viene soddisfatta:
@defer, on viewpoert e when Angular 17
In @defer, è possibile specificare con delle condizioni quando il lazy loading deve avvenire; l’abbiamo già visto con on e when. In Angular 17, esiste anche un’altra parola chiave che si può utilizzare in concomitanza con on e when, e si tratta di prefetch.
Prefetch consente di gestire comportamenti più avanzati, come ad esempio il precaricamento delle risorse prima che l’utente veda e/o interagisca con un blocco @defer, rendendo così determinate risorse disponibili in tempi più brevi.
@defer, Prefetch Angular 17
Per chi si è già approcciato alla versione 16 o 17 di Angular, avrà sicuramente sentito parlare dei Signals (forse fin troppo xD) e dei vantaggi che possono portare alle nostre applicazioni. Ma andiamo con ordine e cerchiamo di capire perché è così importante iniziare a prendere in considerazione l’approccio signals, soprattutto perché man mano diventeranno sempre più uno standard. Spoiler: in Angular 17 già lo sono!
Possiamo immaginare un Signal come un involucro attorno a un valore, in grado di avvisare gli utenti quando questo valore subisce un cambiamento. I Signals posso contenere qualsiasi tipo di valore che va dalle primitive a strutture dati complesse.
I Signals posso essere di due tipologie, writable o read-only. Vediamo ora in cosa consistono le principali differenze.
I writable signals danno la possibilità, tramite una funzione, di aggiornare direttamente il loro valore. Per creare i writable signal ci basta chiamare la funzione signal che conterrà un valore iniziale (un po’ come i BehaviourSubject).
Creare writable signal Angular 17
Possiamo anche settare un nuovo valore e fare un update al valore attuale, con .set(), .update(), vediamo come fare in Angular 17:
.set(), Angular 17
.update(), Angular 17
Diversamente dai writable, i computed signals non possono avere un valore iniziale, ma il loro valore deriva sempre da altri signals.
Computed Signals, Angular 17
Il valore del signal doubleCount sarà sempre dipendente dal valore count, che Angular provvederà ad aggiornare a ogni cambiamento.
Il motivo principale sono le prestazioni!
Angular, quando avviene un cambiamento in un componente, fa un check-in di tutta l’app per verificare se quell’evento riguarda altri componenti. Da questo comportamento si evince che le prestazioni subiscono sicuramente un calo (ovviamente parliamo di app/web app davvero grandi), che con i signals, possiamo almeno in parte, ridurre.
Infatti, Angular, al cambiare dello stato di un signal, farà delle verifiche solo ai componenti collegati, evitando controlli inutili.
Sembra qualcosa di superfluo per progetti di piccole dimensioni, ed effettivamente potrebbe esserlo, però immaginate di dover gestire applicazioni con centinaia o migliaia di componenti, avere i signals è un vantaggio!
Con il rilascio della versione 17, Angular ha introdotto significative semplificazioni nella gestione del server-side rendering (SSR), promettendo un'esperienza migliorata sia per gli utenti che per gli sviluppatori.
Con questa nuova versione, Angular mira a semplificare e ottimizzare il processo di SSR, promuovendo una maggiore efficienza e una migliore user experience (UX).
Lato server il Server-Side Rendering è processo che prevede il rendering delle pagine di un’app, con conseguente contenuto HTML iniziale che contiene lo stato iniziale della pagina. Una volta che il contenuto HTML viene consegnato al browser, Angular inizializza l'applicazione e utilizza i dati contenuti nell' HTML.
In altre parole, l’SSR lato server si occupa di preparare la pagina con tutte le informazioni necessarie, riducendo così la dipendenza dal caricamento completo del file JavaScript nel browser.
Il Server-Side Rendering (SSR) offre una serie di vantaggi significativi rispetto al Client-Side Rendering (CSR), tra cui:
SSR contribuisce al miglioramento delle le applicazioni, fornendo direttamente al client l’HTML rindirizzato. Questo, consente di leggere e analizzare il contenuto prima di caricare il JavaScript, risultandoun vantaggio per tutti quegli utenti che hanno una connessione lenta su dispositivi mobile.
L'implementazione di SSR comporta miglioramenti delle prestazioni che possono essere valutati utilizzando le statistiche Core Web Vitals (CWV), come: la riduzione del First Contentful Paint (FCP), del Largest Contentful Paint (LCP) e Cumulative Layout Shift (CLS).
L’SSR contribuisce alla Search Engine Optimization (SEO) delle applicazioni, facilitandone l'indicizzazione del contenuto dell'applicazione da parte dei motori di ricerca, migliorando la visibilità e la posizione nei risultati di ricerca
L'adozione di SSR non solo ottimizza le prestazioni dell'applicazione, ma ha anche impatti positivi sulla user experience complessiva e sulla visibilità online attraverso i motori di ricerca.
Per i nuovi progetti abbiamo due possibilità per impostare le applicazioni in SSR, la prima è, nel momento in cui creiamo un nuovo progetto con Angular CLI, aggiungere dopo ng new <AppName>, - -ssr:
Impostare le applicazioni in SSR, Angular 17
Se dimentichiamo d’inserire - -ssr, la CLI ci chiederà successivamente se vogliamo un’app in SSR:
Messaggio CLI, Angular 17
Diversamente, se il progetto è già stato inizializzato senza SSR, sempre tramite CLI ci risulterà molto semplice aggiungerlo in un secondo momento:
Aggiungere SSR in un secondo momento
Eccoci qui, a trarre delle conclusioni sul lavoro che il team Angular ha svolto con il rilascio della versione 17.
Come abbiamo visto, le novità non sono poche, ma come sappiamo Angular non smette mai di sorprenderci (nel bene e nel male xD)!
Partendo dal nuovo logo, passando per la nuova documentazione, nuovo flusso di controllo, Signals e SSR si capisce come il team sta cercando di rendere il framework sempre più accessibile e performante, soprattutto per stare al passo con le esigenze del web moderno.
Da sviluppatore, secondo me erano necessari questi aggiornamenti, soprattutto considerando la nuova sintassi del flusso di controllo integrato, che rende lo sviluppo più piacevole, leggibile e performante.
Spero vi sia piaciuto questo piccolo viaggio all’interno di Angular 17, anche se ci sarebbero degli approfondimenti da fare; ma chi lo sa, forse nel prossimo articolo!
Se avete avuto già modo di utilizzare/studiare l’ultima versione, vi invito a condividere feedback e opinioni a riguardo, ma soprattutto ad approfondire tutte le nuove possibilità che ci offre se non lo avete ancora fatto!
Vincenzo Saccotelli
L’autore di questo articolo lavora in Ulixe dal 2022 come Sviluppatore Front-End. Ama le sfide e per lui l’apprendimento non ha mai fine. È una persona un po’ vintage, il che spiega la sua passione per la fotografia analogica, la musica anni 80-90 e le camicie a quadri di flanella. Il viaggio è una costante nella sua.
Torna sul nostro blog per approfondire il mondo dello sviluppo Front-End!
Get in touch
Ulixe Group S.r.l. Copyright © Ulixe Group S.r.l. | Lungo Dora Pietro Colletta, 67, 10153, Torino, Italia | Partita IVA IT03305250122 | Numero Rea TO1173020