Ottimizzazione delle risorse JavaScript per la velocità della pagina
Pubblicato: 2020-05-05L'esempio seguente proviene da un sito Web di notizie ampio e complesso. Perdono traffico organico da anni. La loro sincronizzazione dell'evento DOMContentLoaded è 2615.2 MS. Potresti pensare che le loro dimensioni DOM siano estremamente enormi, ma no...
È quasi uguale a quello raccomandato da Google e in questo documento esistono solo 1230 nodi HTML.
Puoi calcolare la tempistica e l'elaborazione del tuo evento domContentLoaded e confrontarlo con i tuoi concorrenti utilizzando DevTools.
L'esame di questo esempio mostra che la dimensione del DOM non è necessariamente il punto critico. Qui, il problema principale è l' ordine delle risorse : le parti blu nella "Scheda principale" sono per l'analisi HTML. Tuttavia, questo sito Web interrompe il browser con il rendering JavaScript prima che il processo di analisi HTML sia terminato.
(Puoi anche utilizzare la sezione Call Tree per trovare errori simili per il tuo team IT.)
Questo esempio illustra chiaramente l'importanza dell'ottimizzazione delle risorse JavaScript e cosa può andare storto quando trascuri JavaScript nelle ottimizzazioni della velocità della tua pagina.
Questo è il terzo di una serie di quattro articoli. Per comprendere meglio questo articolo, ti consigliamo di leggere i primi due articoli della serie:
- Il rendering di Javascript e la velocità della pagina sono strettamente correlati al modo in cui il motore di rendering di un browser crea una pagina web.
- Dovresti anche comprendere le metriche avanzate della velocità della pagina prima di entrare in questo articolo.
Userò alcuni esempi dei primi due articoli per aiutare a fornire un contesto in questo.
Che cos'è Javascript Rendering e in che modo influisce sulla velocità della tua pagina?
Il rendering Javascript è l'ultima sezione di caricamento della pagina che può modificare in modo interattivo la struttura creata utilizzando DOM e CSSOM. Qualsiasi elemento della pagina può essere modificato in un formato attivabile dall'utente o visualizzato normalmente. Qualsiasi elemento con una proprietà display:none a cui non è stato possibile accedere dall'albero di rendering può essere reso visibile con JavaScript o iniettato tramite diversi elementi HTML nel DOM.
JavaScript interrompe il DOM e il CSSOM perché cambia il DOM e il CSSOM nel momento in cui vengono letti dal browser. Pertanto, per evitare che influisca negativamente sul tempo e sulla velocità di caricamento della pagina, è necessario esaminare la relazione tra il rendering DOM, CSSOM e JavaScript.
Sopra c'è un esempio di un albero di rendering. Tutti gli snippet di codice ad incastro nei nodi CSSOM e HTML hanno equivalenti semantici nell'albero di rendering. Se guardi attentamente, noterai che il nodo HTML "Pulsante di azione" non è nell'albero di rendering. Il motivo principale di ciò è "display:none;" proprietà CSS. A causa di questo comando di invisibilità, non è incluso nell'albero di rendering. Per vedere come sono stati costruiti gli elementi in questo albero, potresti voler leggere il primo articolo di questa serie.
Se hai molti elementi della pagina che non appariranno al primo caricamento perché dipendono dal comportamento dell'utente, nell'ordine di caricamento delle risorse dovrai separare questi elementi e inserirli nell'ultima riga. L'uso di un DOM ombra o di un DOM virtuale sono opzioni migliori a questo punto.
Attributi differiti e asincroni per risorse JavaScript
Se metti i tuoi file JS nella sezione e se non usi gli attributi 'defer' o 'async' probabilmente ritarderà il tuo tempo DOMContentLoaded. Per prevenire questa situazione, possiamo utilizzare questi due attributi. Defer ritarda il processo di caricamento di un file JS mentre "Async" carica JS e altre origini in modo parallelo. Entrambi hanno vantaggi e svantaggi. Parleremo solo dei principali qui.
- Se usi il differimento su un file JS principale, probabilmente non vedrai i suoi effetti "iniziatore" fino a quando non verrà installato.
- Se usi troppo il differimento, potresti causare un collo di bottiglia della CPU alla fine del caricamento della pagina.
Da quando è stato scritto questo articolo, è stato rilasciato l'aggiornamento di Chrome 80. Nella colonna Iniziatore, ora è molto più facile vedere quale risorsa viene chiamata da quale risorsa. Ad esempio, puoi vedere un'immagine o un file CSS chiamato da JS. Se scorri le risorse tenendo premuto il tasto Maiusc, vedrai anche quale risorsa non può essere utilizzata senza caricare altre risorse.
Scorrimento tenendo premuto il tasto Maiusc: il colore rosso indica la risorsa condizionale per la risorsa evidenziata in verde.
Puoi anche utilizzare la nuova sezione Iniziatore di Chrome per una revisione più dettagliata dell'ordine di caricamento delle risorse, dell'iniziatore e della priorità. Ciò consente di rilevare catene di chiamate JS estremamente lunghe e costose come quella di seguito.
Un esempio di una lunga e costosa catena di chiamate JS dallo stesso sito. Sopra la risorsa selezionata ci sono i suoi iniziatori. La parte successiva mostra le risorse avviate dalla risorsa selezionata.
- I file JS posticipati vengono scaricati dopo l'evento domInteractive, quindi è necessario sceglierli in base ai file e alle immagini CSS.
- Se rinvii alcuni file JS di terze parti user-tracker, potresti non essere in grado di tenere traccia di determinati comportamenti degli utenti.
- Il differimento di solito non blocca il processo DOM ma Async lo fa. I file JS con attributi asincroni vengono scaricati dal browser durante l'analisi HTML e l'elaborazione CSSOM.
- Se usi troppo l'attributo async, probabilmente creerai un collo di bottiglia nell'elaborazione della CPU e rallenterai anche i tuoi processi DOM e CSSOM. Devi scegliere con attenzione cosa rinviare o asincronare.
Ecco uno schema di esempio per gli attributi asincroni e differiti. Il primo viene caricato prima di domContentLoaded senza dividere l'analisi HTML durante il recupero. Nel secondo, il file JS recuperato non viene eseguito prima che l'analisi HTML sia terminata.
Suggerimenti e suggerimenti per il rendering e le prestazioni di Javascript
Prima di entrare in esempi pratici, ecco alcuni suggerimenti per migliorare le prestazioni di rendering di JavaScript. Ciò potrebbe anche aiutare a comprendere meglio la velocità della pagina e il funzionamento di un browser.
Non utilizzare variabili non necessarie.
Se sei SEO, potresti notare variabili non necessarie o non utilizzate in un file JavaScript. Esistono molti strumenti che possono essere utilizzati per rilevare questo tipo di errore. Di seguito troverai due esempi di base per variabili non utilizzate e non necessarie.
var carName= marca+ ” ” + anno;
document.getElementById(“demo”).innerHTML = carName;
Qui, la variabile "carName" non è necessaria. Puoi suggerire la seguente modifica:
document.getElementById(“demo”).innerHTML = brand+ ” ” + anno
O:
[a, b, c, d, e].forEach(function (value, index) {
console.log(indice);
});
Qui il parametro “value” non è necessario, perché non viene utilizzato. Puoi rimuoverlo:
[a, b, c, d, e].forEach(funzione (indice) {
console.log(indice);
});
Sul lato destro puoi vedere tempi di connessione più lunghi (linee bianche) e i file CSS e JS vengono caricati in ordine asimmetrico grazie a Javascript "asincroni".
Sul lato sinistro, i tempi di connessione sono più brevi e i file CSS e JS non vengono mischiati perché ogni sorgente viene caricata in righe. Gli attributi asincroni possono ridurre il tuo indice di velocità in quanto può estendere il tempo TBT, quindi è necessario eseguire un'indagine e segnalarlo al team di sviluppatori per i file JS del tracker delle prestazioni dalla scheda delle prestazioni, oppure puoi eseguire alcuni esperimenti da solo.
Usa gli strumenti per compiti difficili
Per un principiante nel codice, trovare variabili non necessarie o non utilizzate può essere difficile. Potresti voler utilizzare alcuni strumenti per queste attività, come Chrome DevTools o pacchetti Node.js come Unused (Kami/node-unused: un modulo che segnala variabili definite, ma non utilizzate nel tuo codice o per più variabili inutilizzate). Se trovi anche qualche piccolo errore, credo che il tuo team IT ti ascolterà per migliorare i tuoi file JavaScript.
Utilizzo del rapporto sulla copertura di Chrome DevTools per trovare il codice JavaScript inutilizzato
Il rapporto sulla copertura di Chrome DevTools mostra frammenti di codice JavaScript inutilizzati ma non è molto pratico. Potresti pensare di poter eliminare ogni parte rossa dal codice ma non è il caso... Dovresti invece trovare funzioni o variabili completamente inutilizzate per un gran numero di pagine di categoria. In questo modo, il tuo team di sviluppatori può essere convinto a utilizzare un processo TreeShaking.
TreeShaking significa eliminare il codice morto dai file. Consiglio di imparare a usare variabili JS inutilizzate e pacchetti di ricerca di funzioni per guadagnare tempo.
Una dimensione DOM più piccola aiuterà anche con il rendering JavaScript. Ogni comando (getElementsByTagName) eseguirà la scansione del tuo DOM. Una dimensione DOM più piccola richiederà meno risorse dal tuo browser e dalla CPU/rete del tuo dispositivo durante il rendering di JavaScript.
Con il nuovo aggiornamento di Chrome 80, anche il rapporto sulla copertura ha subito una modifica. Sono state aggiunte opzioni Per funzione e Per blocco opzionali. Per blocco è il valore predefinito qui.
Se scegli Per funzione, vedrai una grande differenza nel tuo rapporto. Il motivo principale di questa situazione è che la vista Per funzione controlla se tutta la funzione viene utilizzata o meno. Se viene utilizzato il 95% della funzione, l'opzione Per funzione lo definirà come codice inutilizzato perché il 5% del codice non viene utilizzato, sebbene venga utilizzata la maggior parte della funzione.
Comprimi, riduci a icona o stordisci i tuoi file JS.
Questo può essere fatto in due modi. Innanzitutto, elimina gli spazi e i commenti non necessari. In secondo luogo, utilizza operatori JavaScript migliorati per i tuoi file JS e modifica nomi, variabili e funzioni con tecnologie pronte all'uso.
Dovresti conoscere le funzioni freccia per questo tipo di compressione. Ad esempio, invece di questo esempio di 84 caratteri:
funzione freccia Islev (a, b) {
console.log (a + b);
}
arrowFonksiyon (5, 6);
Puoi comprimerlo a soli 50 caratteri con le funzioni freccia =>
const ab = (a, b) => b + a;
console.log (ab (5, 6));
Un altro metodo di abbreviazione/compressione è valido per le istruzioni If. Invece di questo frammento di codice con 63 caratteri:
se (a<b) {
console.log(ab);
}
altro {
console.log(a+b);
Puoi usare quello con 43 caratteri di seguito:
(a<b) ? console.log(ab): console.log(a+b);
Puoi anche suggerire al tuo team IT di utilizzare i segni $ e _ per la compressione. La maggior parte dei file JavaScript funziona per reinterpretare DOM. A questo, potresti vedere un sacco di document.getElementById(x); frammenti di codice nei file. Puoi usare un segno $ per questa attività. Questo ti salverà da un enorme mucchio di dimensioni inutili.
La maggior parte delle librerie JavaScript utilizza $ per impostazione predefinita per la definizione delle funzioni, ma non tutte, poiché $ è anche un carattere alfabetico.
In questa situazione potresti suggerire al tuo team IT di utilizzare:
funzione $(x) {return document.getElementById(x);} .
Usa un tipo di rendering appropriato
JavaScript e tipi di rendering di pagine web in termini di compatibilità SEO.
SSR Hydration significa che alcuni dei componenti JS verranno renderizzati utilizzando Client Side Rendering. È utile per FP e FMP, ma possono esserci alcuni aspetti negativi per i punteggi TTI e Speed Index.
Fonte immagine: Notprovided.eu
Best practice di codifica per le prestazioni di rendering JavaScript
- Un altro importante contributo alla compressione verrà dall'utilizzo di "_". Puoi utilizzare "underscore.js" per migliorare i formati e le funzioni di scrittura JavaScript. In questo modo creerai file JS più piccoli manipolando elenchi e raccolte con funzioni JS più brevi senza funzioni JS integrate.
- Anche l'uso di molti cambiamenti variabili lunghi ed estenuanti e l'inquinamento variabile globale sono fonti di rendering lento. Dovresti determinare le scelte di ambito generale delle tue funzioni e i tipi di variabile globale/variabile lunga. L'uso di variabili locali con 'Let' è migliore per il rendering. A causa delle variabili locali, i browser non controlleranno altre variabili di funzioni globali per la modifica successiva.
Per simulare un esame delle prestazioni più realistico, ad esempio, ciò che potresti vedere sui telefoni cellulari di fascia bassa, dovresti utilizzare le preferenze di limitazione della CPU e connessione 3G veloce/lenta in Chrome DevTools.
Fonte immagine: Addy Osmani
- L'uso di funzioni JS più piccole e catene di variabili aiuterà le tue prestazioni di rendering. Inoltre, è meglio usare il selettore "questo" invece del selettore "con". Il selettore “This” in Javascript è un codice di funzionamento locale a differenza di “with”, la stessa logica con let e var è valida anche qui.
- Se usi le tue istruzioni nei frammenti di codice del ciclo For, anche questo rallenterà leggermente la velocità di rendering. Perché la tua istruzione di funzione scorrerà attraverso ogni elemento del ciclo. Puoi semplicemente creare una nuova variabile per gli elementi del ciclo e puoi chiamare questi elementi con una funzione che è al di fuori del ciclo For.
- Se vuoi raggiungere un elemento HTML più volte, puoi creare una variabile per esso e puoi chiamarlo con le funzioni che desideri. Raggiungere un elemento HTML con JavaScript non è un processo veloce. Potresti semplicemente creare più di un onere per il tuo browser.
Un altro modo per migliorare le prestazioni di rendering di Javascript è il rendering trisomorfo tramite Service Workers. Puoi inserire alcuni dei tuoi file JS nella memoria del browser del client per sessioni future. In questo modo, puoi far funzionare il tuo sito web offline.
Puoi trovare una semplice demo per una migliore comprensione e un'opportunità per esercitarti con gli operatori dei servizi qui
Allineamento: in che modo l'ottimizzazione di JavaScript e la velocità della pagina influisce sulla SEO
Per impedire alle risorse JavaScript di sabotare la velocità della tua pagina, abbiamo visto come Defer e Async possono fare un'enorme differenza. Abbiamo anche esaminato alcune strategie di "debug" e suggerimenti per la codifica che possono aiutarti a migliorare la velocità delle tue pagine con risorse JavaScript.
Ora che abbiamo visto come i browser creano pagine Web, come viene misurata e influenzata la velocità della pagina e il ruolo svolto dall'ottimizzazione di JavaScript nel tempo di caricamento della pagina, il prossimo articolo dimostrerà come l'ordine di caricamento delle risorse influisce sulla velocità della pagina e sul budget di scansione.
Se sei interessato a rivedere i precedenti articoli di questa serie di quattro articoli, puoi trovarli qui:
- “Come fa un browser a creare una pagina web”
- "Metriche avanzate della velocità della pagina".