Rendering lato client di HTML e interattività

Il rendering HTML con JavaScript è diverso dal rendering HTML inviato dal server e questo può influire sulle prestazioni. Scopri la differenza in questa guida e cosa puoi fare per preservare le prestazioni di rendering del tuo sito web, soprattutto per quanto riguarda le interazioni.

L'analisi e il rendering del codice HTML sono operazioni che i browser eseguono molto bene per impostazione predefinita per i siti web che utilizzano la logica di navigazione integrata del browser, a volte chiamata "caricamento pagina tradizionale" o "navigazione rigida". Questi siti web vengono talvolta chiamati applicazioni multipagina (MPA).

Tuttavia, gli sviluppatori possono aggirare le impostazioni predefinite del browser per soddisfare le esigenze delle loro applicazioni. Questo è sicuramente il caso dei siti web che utilizzano il pattern di applicazione a pagina singola (SPA), che crea dinamicamente grandi parti del codice HTML/DOM sul client con JavaScript. Il rendering lato client è il nome di questo pattern di progettazione e può avere effetti sull'Interaction to Next Paint (INP) del tuo sito web se il lavoro richiesto è eccessivo.

Questa guida ti aiuterà a valutare la differenza tra l'utilizzo dell'HTML inviato dal server al browser e la sua creazione sul client con JavaScript, nonché il modo in cui quest'ultimo può comportare un'elevata latenza di interazione in momenti cruciali.

Come il browser esegue il rendering dell'HTML fornito dal server

Il pattern di navigazione utilizzato nei caricamenti di pagina tradizionali prevede la ricezione di HTML dal server a ogni navigazione. Se inserisci un URL nella barra degli indirizzi del browser o fai clic su un link in un'app multipiattaforma, si verifica la seguente serie di eventi:

  1. Il browser invia una richiesta di navigazione per l'URL fornito.
  2. Il server risponde con l'HTML in blocchi.

L'ultimo passaggio è fondamentale. È anche una delle ottimizzazioni delle prestazioni più fondamentali nello scambio tra server e browser ed è nota come streaming. Se il server può iniziare a inviare l'HTML il prima possibile e il browser non attende l'arrivo dell'intera risposta, il browser può elaborare l'HTML in blocchi man mano che arriva.

Uno screenshot dell'analisi dell'HTML inviato dal server visualizzato nel riquadro Prestazioni di Chrome DevTools. Man mano che l'HTML viene trasmesso, i suoi blocchi vengono elaborati in più attività più brevi e il rendering è incrementale.
Analisi e rendering dell'HTML fornito dal server, come visualizzato nel riquadro Prestazioni di Chrome DevTools. Le attività relative all'analisi dell'HTML e al relativo rendering sono suddivise in blocchi.

Come la maggior parte delle cose che accadono nel browser, l'analisi dell'HTML avviene all'interno delle attività. Quando l'HTML viene trasmesso in streaming dal server al browser, quest'ultimo ottimizza l'analisi dell'HTML eseguendola un po' alla volta man mano che i bit dello stream arrivano in blocchi. Di conseguenza, il browser cede periodicamente il controllo al thread principale dopo l'elaborazione di ogni blocco, evitando così attività lunghe. Ciò significa che altre attività possono essere eseguite durante l'analisi dell'HTML, tra cui il lavoro di rendering incrementale necessario per presentare una pagina all'utente, nonché l'elaborazione delle interazioni dell'utente che potrebbero verificarsi durante il periodo cruciale di avvio della pagina. Questo approccio si traduce in un punteggio Interaction to Next Paint (INP) migliore per la pagina.

Le nostre conclusioni? Quando esegui lo streaming di HTML dal server, ottieni l'analisi e il rendering incrementali dell'HTML e la cessione automatica al thread principale senza costi aggiuntivi. Questo non avviene con il rendering lato client.

Come il browser esegue il rendering dell'HTML fornito da JavaScript

Sebbene ogni richiesta di navigazione a una pagina richieda che il server fornisca una certa quantità di HTML, alcuni siti web utilizzano il pattern SPA. Questo approccio spesso prevede che il server fornisca un payload iniziale minimo di HTML, ma poi il client compila l'area dei contenuti principali di una pagina con l'HTML assemblato dai dati recuperati dal server. Le navigazioni successive, a volte chiamate "navigazioni soft" in questo caso, vengono gestite interamente da JavaScript per compilare la pagina con un nuovo codice HTML.

Il rendering lato client può verificarsi anche in siti non SPA in casi più limitati in cui l'HTML viene aggiunto dinamicamente al DOM tramite JavaScript.

Esistono alcuni modi comuni per creare codice HTML o aggiungerlo al DOM tramite JavaScript:

  1. La proprietà innerHTML consente di impostare i contenuti di un elemento esistente tramite una stringa, che il browser analizza nel DOM.
  2. Il metodo document.createElement consente di creare nuovi elementi da aggiungere al DOM senza utilizzare l'analisi HTML del browser.
  3. Il metodo document.write consente di scrivere codice HTML nel documento (e il browser lo analizza, proprio come nell'approccio n. 1). Tuttavia, per una serie di motivi, l'utilizzo di document.write è fortemente sconsigliato.
Uno screenshot dell'analisi dell'HTML visualizzato tramite JavaScript nel riquadro Prestazioni di Chrome DevTools. Il lavoro viene eseguito in un'unica attività lunga che blocca il thread principale.
Analisi e rendering di HTML tramite JavaScript sul client, come visualizzato nel riquadro Prestazioni di Chrome DevTools. Le attività di analisi e rendering non sono suddivise in blocchi, il che si traduce in un'attività lunga che blocca il thread principale.

Le conseguenze della creazione di HTML/DOM tramite JavaScript lato client possono essere significative:

  • A differenza dell'HTML trasmesso in streaming dal server in risposta a una richiesta di navigazione, le attività JavaScript sul client non vengono suddivise automaticamente in blocchi, il che potrebbe comportare attività lunghe che bloccano il thread principale. Ciò significa che l'INP della tua pagina può essere influenzato negativamente se crei troppi elementi HTML/DOM contemporaneamente sul client.
  • Se l'HTML viene creato sul client durante l'avvio, le risorse a cui fa riferimento non verranno rilevate dallo scanner di precaricamento del browser. Questo avrà sicuramente un effetto negativo sulla metrica Largest Contentful Paint (LCP) di una pagina. Anche se non si tratta di un problema di prestazioni di runtime (ma di un problema di ritardo della rete nel recupero di risorse importanti), non vuoi che l'LCP del tuo sito web venga influenzato dall'elusione di questa ottimizzazione fondamentale delle prestazioni del browser.

Cosa puoi fare per ridurre l'impatto del rendering lato client sulle prestazioni

Se il tuo sito web dipende molto dal rendering lato client e hai osservato valori INP scarsi nei dati dei campi, potresti chiederti se il rendering lato client abbia a che fare con il problema. Ad esempio, se il tuo sito web è una SPA, i dati dei campi potrebbero rivelare interazioni responsabili di un notevole lavoro di rendering.

Qualunque sia la causa, di seguito sono riportati alcuni potenziali motivi che puoi esaminare per rimettere le cose in carreggiata.

Fornisci quanto più codice HTML possibile dal server

Come accennato in precedenza, per impostazione predefinita il browser gestisce l'HTML dal server in modo molto efficiente. In questo modo, l'analisi e il rendering dell'HTML verranno suddivisi in modo da evitare attività lunghe e ottimizzare il tempo totale del thread principale. Ciò porta a un Total Blocking Time (TBT) inferiore, che è fortemente correlato a INP.

Potresti fare affidamento su un framework di frontend per creare il tuo sito web. In questo caso, assicurati di eseguire il rendering dell'HTML del componente sul server. In questo modo, limiterai la quantità di rendering lato client iniziale richiesto dal tuo sito web e dovresti ottenere un'esperienza migliore.

  • Per React, ti consigliamo di utilizzare l'API Server DOM per eseguire il rendering dell'HTML sul server. Tuttavia, tieni presente che il metodo tradizionale di rendering lato server utilizza un approccio sincrono, che può comportare un Time to First Byte (TTFB) più lungo, nonché metriche successive come First Contentful Paint (FCP) e LCP. Se possibile, assicurati di utilizzare le API di streaming per Node.js o altri runtime JavaScript in modo che il server possa iniziare a trasmettere l'HTML al browser il prima possibile. Next.js, un framework basato su React, fornisce molte best practice per impostazione predefinita. Oltre a eseguire automaticamente il rendering dell'HTML sul server, può anche generare staticamente l'HTML per le pagine che non cambiano in base al contesto dell'utente (ad esempio l'autenticazione).
  • Anche Vue esegue il rendering lato client per impostazione predefinita. Tuttavia, come React, Vue può anche eseguire il rendering dell'HTML del componente sul server. Sfrutta queste API lato server, se possibile, o prendi in considerazione un'astrazione di livello superiore per il tuo progetto Vue per semplificare l'implementazione delle best practice.
  • Svelte esegue il rendering dell'HTML sul server per impostazione predefinita, anche se se il codice del componente richiede l'accesso a spazi dei nomi esclusivi del browser (ad esempio window), potresti non essere in grado di eseguire il rendering dell'HTML del componente sul server. Esplora approcci alternativi, ove possibile, in modo da non causare un rendering lato client non necessario. SvelteKit, che sta a Svelte come Next.js sta a React, incorpora il maggior numero possibile di best practice nei tuoi progetti Svelte, in modo da evitare potenziali trappole nei progetti che utilizzano solo Svelte.

Limita la quantità di nodi DOM creati sul client

Quando i DOM sono di grandi dimensioni, l'elaborazione necessaria per eseguirne il rendering tende ad aumentare. Indipendentemente dal fatto che il tuo sito web sia una SPA completa o che inserisca nuovi nodi in un DOM esistente come risultato di un'interazione per un'MPA, ti consigliamo di mantenere questi DOM il più piccoli possibile. In questo modo, si riduce il lavoro richiesto durante il rendering lato client per visualizzare l'HTML, contribuendo così a mantenere più basso l'INP del tuo sito web.

Valuta un'architettura di service worker per il servizio di streaming

Si tratta di una tecnica avanzata, che potrebbe non funzionare facilmente con ogni caso d'uso, ma che può trasformare la tua MPA in un sito web che sembra caricarsi istantaneamente quando gli utenti navigano da una pagina all'altra. Puoi utilizzare un service worker per pre-memorizzare nella cache le parti statiche del tuo sito web in CacheStorage utilizzando l'API ReadableStream per recuperare il resto dell'HTML di una pagina dal server.

Se utilizzi questa tecnica con successo, non crei codice HTML sul client, ma il caricamento istantaneo di parti di contenuti dalla cache darà l'impressione che il tuo sito si carichi rapidamente. I siti web che utilizzano questo approccio possono sembrare quasi una SPA, ma senza gli svantaggi del rendering lato client. Inoltre, riduce la quantità di codice HTML richiesto al server.

In breve, un'architettura di service worker di streaming non sostituisce la logica di navigazione integrata del browser, ma la integra. Per saperne di più su come ottenere questo risultato con Workbox, leggi Applicazioni multipagina più veloci con gli stream.

Conclusione

Il modo in cui il tuo sito web riceve ed esegue il rendering del codice HTML influisce sul rendimento. Quando ti affidi al server per inviare tutto (o la maggior parte) dell'HTML necessario per il funzionamento del tuo sito web, ottieni molti vantaggi senza costi aggiuntivi: analisi e rendering incrementali e trasferimento automatico al thread principale per evitare attività lunghe.

Il rendering HTML lato client introduce una serie di potenziali problemi di prestazioni che in molti casi possono essere evitati. Tuttavia, a causa dei requisiti di ogni singolo sito web, non è del tutto evitabile nel 100% dei casi. Per ridurre le potenziali attività lunghe che possono derivare da un rendering eccessivo sul client, assicurati di inviare dal server la maggior parte possibile del codice HTML del tuo sito web, mantieni le dimensioni del DOM il più ridotte possibile per l'HTML di cui deve essere eseguito il rendering sul client e prendi in considerazione architetture alternative per velocizzare la pubblicazione dell'HTML sul client, sfruttando al contempo l'analisi e il rendering incrementali forniti dal browser per l'HTML caricato dal server.

Se riesci a ridurre al minimo il rendering lato client del tuo sito web, migliorerai non solo l'INP del tuo sito web, ma anche altre metriche come LCP, TBT e, in alcuni casi, anche il TTFB.