Lato client, lato server e pre-rendering per le app Web
Pubblicato: 2022-03-11C'è qualcosa che sta succedendo all'interno della comunità front-end di recente. Il rendering lato server sta ottenendo sempre più trazione grazie a React e alla sua funzione di idratazione lato server integrata. Ma non è l'unica soluzione per offrire un'esperienza veloce all'utente con un punteggio TTFB (time-to-first-byte) super veloce: anche il pre-rendering è una strategia piuttosto buona. Qual è la differenza tra queste soluzioni e un'applicazione completamente renderizzata dal client?
Applicazione resa dal cliente
Poiché esistono framework come Angular, Ember.js e Backbone, gli sviluppatori front-end tendono a eseguire il rendering di tutto lato client. Grazie a Google e alla sua capacità di "leggere" JavaScript, funziona abbastanza bene ed è anche SEO friendly.
Con una soluzione di rendering lato client, reindirizzi la richiesta a un singolo file HTML e il server la consegnerà senza alcun contenuto (o con una schermata di caricamento) fino a quando non recuperi tutto il JavaScript e lascia che il browser compili tutto prima di eseguire il rendering del contenuto.
Con una connessione Internet buona e affidabile, è abbastanza veloce e funziona bene. Ma può essere molto meglio, e non deve essere difficile farlo in questo modo. Questo è ciò che vedremo nelle sezioni seguenti.
Rendering lato server (SSR)
Una soluzione SSR è qualcosa che facevamo molto, molti anni fa, ma tendiamo a dimenticare a favore di una soluzione di rendering lato client.
Con le vecchie soluzioni di rendering lato server, creavi una pagina Web, ad esempio con PHP, il server compilava tutto, includeva i dati e consegnava al client una pagina HTML completamente popolata. È stato veloce ed efficace.
Ma... ogni volta che passavi a un altro percorso, il server doveva rifare il lavoro da capo: ottenere il file PHP, compilarlo e consegnare l'HTML, con tutti i CSS e JS che ritardavano il caricamento della pagina a poche centinaia di ms o anche interi secondi.
E se potessi caricare la prima pagina con la soluzione SSR e quindi utilizzare un framework per eseguire il routing dinamico con AJAX, recuperando solo i dati necessari?
Questo è il motivo per cui SSR sta ottenendo sempre più trazione all'interno della comunità perché React ha reso popolare questo problema con una soluzione facile da usare: il metodo RenderToString
.
Questo nuovo tipo di applicazione web è chiamato app universale o app isomorfa . C'è ancora qualche controversia sui significati esatti di questi termini e sulla relazione tra loro, ma molte persone li usano in modo intercambiabile.
Ad ogni modo, il vantaggio di questa soluzione è la possibilità di sviluppare un'app lato server e lato client con lo stesso codice e offrire all'utente un'esperienza davvero veloce con dati personalizzati. Lo svantaggio è che è necessario eseguire un server.
SSR viene utilizzato per recuperare i dati e precompilare una pagina con contenuti personalizzati, sfruttando l'affidabile connessione Internet del server. Cioè, la connessione Internet del server è migliore di quella di un utente con lie-fi), quindi è in grado di precaricare e amalgamare i dati prima di consegnarli all'utente.
Con i dati precompilati, l'utilizzo di un'app SSR può anche risolvere un problema che le app renderizzate dal client hanno con la condivisione social e il sistema OpenGraph. Ad esempio, se hai un solo file index.html
da consegnare al cliente, avrà solo un tipo di metadati, molto probabilmente i metadati della tua home page. Questo non verrà contestualizzato quando desideri condividere un percorso diverso, quindi nessuno dei tuoi percorsi verrà mostrato su altri siti con il proprio contenuto utente (descrizione e immagine di anteprima) che gli utenti vorrebbero condividere con il mondo.
Pre-rendering
Il server obbligatorio per un'app universale può essere un deterrente per alcuni e potrebbe essere eccessivo per una piccola applicazione. Questo è il motivo per cui il pre-rendering può essere davvero un'ottima alternativa.
Ho scoperto questa soluzione con Preact e la sua CLI che ti consente di compilare tutti i percorsi preselezionati in modo da poter archiviare un file HTML completamente popolato su un server statico . Ciò ti consente di offrire un'esperienza super veloce all'utente, grazie alla funzione di idratazione Preact/React, senza la necessità di Node.js.
Il problema è che, poiché questo non è SSR, non hai dati specifici dell'utente da mostrare a questo punto: è solo un file statico (e alquanto generico) inviato direttamente alla prima richiesta, così com'è. Quindi, se disponi di dati specifici dell'utente, qui è dove puoi integrare uno scheletro ben progettato per mostrare all'utente che i loro dati stanno arrivando, per evitare qualche frustrazione da parte loro:
C'è un altro problema: affinché questa tecnica funzioni, è comunque necessario disporre di un proxy o qualcosa per reindirizzare l'utente al file corretto.

Come mai?
Con un'applicazione a pagina singola, devi reindirizzare tutte le richieste al file radice, quindi il framework reindirizza l'utente con il suo sistema di routing integrato. Quindi il caricamento della prima pagina è sempre lo stesso file radice.
Affinché una soluzione di pre-rendering funzioni, devi comunicare al tuo proxy che alcuni percorsi richiedono file specifici e non sempre il file index.html
radice.
Ad esempio, supponiamo di avere quattro percorsi ( /
, /about
, /jobs
e blog
) e tutti hanno layout diversi. Hai bisogno di quattro diversi file HTML per fornire lo scheletro all'utente che lascerà quindi React/Preact/etc. reidratarlo con i dati. Quindi, se reindirizzi tutti quei percorsi al file index.html
radice, la pagina avrà una sensazione spiacevole e glitch durante il caricamento, per cui l'utente vedrà lo scheletro della pagina sbagliata fino al termine del caricamento e alla sostituzione del layout. Ad esempio, l'utente potrebbe vedere uno scheletro della home page con una sola colonna, quando ha chiesto una pagina diversa con una galleria simile a Pinterest.
La soluzione è dire al tuo proxy che ognuno di questi quattro percorsi ha bisogno di un file specifico:
-
https://my-website.com
→ Reindirizza al fileindex.html
radice -
https://my-website.com/about
→ Reindirizzamento al file/about/index.html
-
https://my-website.com/jobs
→ Reindirizzamento al file/jobs/index.html
-
https://my-website.com/blog
→ Reindirizzamento al file/blog/index.html
Questo è il motivo per cui questa soluzione può essere utile per piccole applicazioni: puoi vedere quanto sarebbe doloroso se avessi poche centinaia di pagine.
A rigor di termini, non è obbligatorio farlo in questo modo: potresti semplicemente usare direttamente un file statico. Ad esempio, https://my-website.com/about/
funzionerà senza alcun reindirizzamento perché cercherà automaticamente un index.html
all'interno della sua directory. Ma hai bisogno di questo proxy se hai URL param: https://my-website.com/profile/guillaume
dovrà reindirizzare la richiesta a /profile/index.html
con il suo layout, perché profile/guillaume/index.html
non esiste e attiverà un errore 404.
In breve, ci sono tre viste di base in gioco con le strategie di rendering sopra descritte: una schermata di caricamento, uno scheletro e l'intera pagina una volta che è stata finalmente renderizzata.
A seconda della strategia, a volte utilizziamo tutte e tre queste viste ea volte passiamo direttamente a una pagina con rendering completo. Solo in un caso d'uso siamo costretti a utilizzare un approccio diverso:
Metodo | Atterraggio (es / ) | Statico (es /about ) | Dinamica fissa (es /news ) | Dinamica parametrizzata (es /users/:user-id ) |
---|---|---|---|---|
Rendering dal cliente | Caricamento → Completo | Caricamento → Completo | Caricamento → Scheletro → Completo | Caricamento → Scheletro → Completo |
Pre-renderizzato | Completo | Completo | Scheletro → Completo | HTTP 404 (pagina non trovata) |
Pre-renderizzato con proxy | Completo | Completo | Scheletro → Completo | Scheletro → Completo |
SSR | Completo | Completo | Completo | Completo |
Il rendering solo client spesso non è sufficiente
Le applicazioni renderizzate dal client sono qualcosa che dovremmo evitare ora perché possiamo fare di meglio per l'utente. E fare meglio, in questo caso, è facile come la soluzione di pre-rendering. È sicuramente un miglioramento rispetto al rendering solo client e più facile da implementare rispetto a un'applicazione con rendering completamente lato server.
Un'applicazione SSR/universale può essere davvero potente se si dispone di un'applicazione di grandi dimensioni con molte pagine diverse. Consente ai tuoi contenuti di essere focalizzati e pertinenti quando parli con un social crawler. Questo vale anche per i robot dei motori di ricerca, che ora tengono conto delle prestazioni del tuo sito quando lo classifica.
Resta sintonizzato per un tutorial di follow-up, in cui illustrerò la trasformazione di una SPA in versioni pre-renderizzate e SSR e confronterò le loro prestazioni.