Angular day, ep. 4: Michel Murabito parla di server-side rendering. Come funziona e perché esiste.

Angular day 2018: The Server-Side Menace, ovvero sulla via jedi della forza di Angular Universal il nostro jedi Michel porterà ci.

“No! Try Not! Do. Or do not. There is no try” – Yoda, The Empire Strikes Back

Detto in parole povere, Universal è una tecnologia che consente di eseguire applicazioni Angular sul server, invece che nel browser, tramite un processo chiamato Server-Side Rendering (SSR).

Le “normali” applicazioni Angular hanno infatti la peculiarità di essere interamente eseguite nel browser, visualizzando il DOM di risposta verso l’utente in pagine HTML, abitualmente in quelle che vengono chiamate Single Page Applications (SPA). Questo ha l’indubbio vantaggio, una volta caricata in memoria l’applicazione, di una responsività più elevata dell’applicazione stessa, e quindi di una user experience migliore.

Non è sempre oro però quello che luccica, e l’esecuzione interamente client-side porta con sé una serie di problematiche. Lo scopo di Universal è precisamente quello di risolvere queste difficoltà.

Tempi di caricamento

Abbiamo detto che un’applicazione Angular standard viene interamente eseguita nel browser, di conseguenza l’utente non vedrà nulla finché non è stato tutto caricato in memoria ed eseguito. Fino ad allora sarà solo una schermata vuota.

Di converso, Universal effettua il pre-rendering della struttura della pagina lato server, in modo che l’utente possa almeno vedere un template nel frattempo che vengono caricati i dati.

Il flusso è più o meno così:

  • Il client manda una richiesta HTTP GET al server
  • Il server effettua il rendering di una pagina HTML che contiene quanto segue:
    • Il template HTML renderizzato da ServerDomRenderer, che l’utente vede all’inizio
    • JavaScript Inline per il preboot
  • Il browser riceve il “payload” (i dati) iniziale dal server
  • L’utente vede la server view
  • Il Preboot inizia a registrare eventi
  • Vengono inviate le richieste per risorse aggiuntive come immagini esterne, file CSS, etc
  • Caricate le risorse esterne inizia il bootstrap (avviamento) di Angular lato client
  • Viene renderizzata la client view
  • Il bootstrap è completo, e il Preboot è concluso
  • Gli eventi di Preboot vengono rieseguiti per allineare lo stato dell’applicazione per riportare eventuali modifiche apportate dall’utente prima del bootstrap (click di un bottone, inserimento dati in una textbox, etc)

Questo flusso, come si vede sotto, accorcia notevolmente i tempi in cui l’utente è in grado di iniziare a fruire dell’applicazione, migliorando anche la performance in generale, specialmente sui device più limitati.

Impatti di Angular sulle performance

Social media

Il web scraping è oramai comune sul web, un esempio comune è Open Graph di Facebook, una API che consente a Facebook di visualizzare i famosi “snippet” quando si inseriscono hyperlink ad altre pagine.

Esempio di visualizzazione di un link esterno su Facebook grazie a Open Graph

Il problema è che i web scraper vogliono pagine HTML, e ovviamente se una pagina deve prima arrivare sul browser per essere renderizzata, lo scraper non è in grado di elaborarla. Inoltre la maggior parte di questi tool non sono in grado di eseguire JavaScript. La possibilità di servire pagine statiche pre-digerite, anche se incomplete favorisce enormemente il processo

SEO

I web crawler sono i bot che navigano il web alla ricerca di contenuti da indicizzare, il concetto stesso di SEO (Search Engine Optimization) è basato sull’operato di questi bot. Così come i social media, anche i crawler hanno le loro esigenze: vogliono vedere un titolo (<title>), vogliono una meta-description, e avendo necessità di “capire” il contenuto di un sito, vogliono anche più contenuto rispetto ai primi. Rispetto ai social media, i crawler (specialmente Google) sono di solito in grado di eseguire JavaScript e capire il contesto di visualizzazione, ma è comunque preferibile un pre rendering nel caso il crawler non dovesse riuscire a venirne a capo.

LINK

Angular Universal

Angular Universal (Angular 2 Server Rendering)

Server-Side Rendering in Angular 2 with Angular Universal

Angular Universal & Firebase functions: The missing guide