In occasione della conferenza Google IO 2018, abbiamo presentato una raccolta di strumenti, librerie e tecniche di ottimizzazione che semplificano il miglioramento del rendimento del web. Qui li spieghiamo utilizzando l'app Oodles Theater. Parliamo anche dei nostri esperimenti con il caricamento predittivo e la nuova iniziativa Guess.js.
Nell'ultimo anno abbiamo lavorato duramente per capire come rendere il web più veloce e con un rendimento migliore. Questo ha portato a nuovi strumenti, approcci e librerie che vorremmo condividere con te in questo articolo. Nella prima parte, ti mostreremo alcune tecniche di ottimizzazione che abbiamo utilizzato nella pratica durante lo sviluppo dell'app Oodles Theater. Nella seconda parte, parleremo dei nostri esperimenti con il caricamento predittivo e la nuova iniziativa Guess.js.
La necessità di prestazioni
Internet diventa sempre più pesante ogni anno. Se controlliamo lo stato del web, possiamo vedere che una pagina mediana sui dispositivi mobili pesa circa 1,5 MB, per la maggior parte JavaScript e immagini.
Le dimensioni crescenti dei siti web, insieme ad altri fattori, come la latenza della rete, le limitazioni della CPU, i pattern di blocco del rendering o il codice superfluo di terze parti, contribuiscono a creare un complicato puzzle delle prestazioni.
La maggior parte degli utenti valuta la velocità come il fattore più importante nella gerarchia della UX in base alle proprie esigenze. Non è troppo sorprendente, perché non puoi fare molto finché il caricamento di una pagina non è terminato. Non puoi ricavare valore dalla pagina né ammirarne l'estetica.
Sappiamo che il rendimento è importante per gli utenti, ma può anche sembrare un segreto scoprire da dove iniziare a ottimizzare. Fortunatamente, esistono strumenti che possono aiutarti in questo percorso.
Lighthouse: una base per il flusso di lavoro relativo alle prestazioni
Lighthouse fa parte di Chrome DevTools e ti consente di eseguire un controllo del tuo sito web e di ricevere suggerimenti su come migliorarlo.
Di recente abbiamo lanciato una serie di nuovi controlli delle prestazioni molto utili nel flusso di lavoro di sviluppo quotidiano.
Vediamo come puoi sfruttarli con un esempio pratico: l'app Oodles Theater. Si tratta di una piccola app web di dimostrazione, dove puoi provare alcuni dei nostri Doodle di Google interattivi preferiti e persino giocare a un paio di giochi.
Durante la creazione dell'app, volevamo assicurarci che avesse il rendimento migliore possibile. Il punto di partenza per l'ottimizzazione è stato un report Lighthouse.
Il rendimento iniziale della nostra app, come indicato nel report Lighthouse, era piuttosto pessimo. Su una rete 3G, l'utente doveva attendere 15 secondi per la prima visualizzazione significativa o per attivare l'interattività dell'app. Lighthouse ha evidenziato una serie di problemi con il nostro sito e il voto complessivo del rendimento di 23 rispecchia esattamente questo.
La pagina pesava circa 3,4 MB: dovevamo assolutamente tagliare qualcosa.
È iniziata così la nostra prima sfida in termini di rendimento: trovare elementi che possiamo rimuovere facilmente senza influire sull'esperienza complessiva.
Opportunità di ottimizzazione delle prestazioni
Rimuovi le risorse non necessarie
Esistono alcuni elementi evidenti che possono essere rimossi in tutta sicurezza: spazi vuoti e commenti.
Lighthouse mette in evidenza questa opportunità nel controllo CSS e JavaScript non minimizzati. Utilizzavamo webpack per la nostra procedura di compilazione, quindi per ottenere la minimizzazione abbiamo semplicemente utilizzato il plug-in Uglify JS.
La minimizzazione è un'attività comune, quindi dovresti essere in grado di trovare una soluzione pronta per qualsiasi processo di compilazione tu stia utilizzando.
Un altro controllo utile in questo spazio è Attiva la compressione del testo. Non c'è motivo di inviare file non compressi e la maggior parte delle CDN lo supporta out-of-the-box.
Utilizzavamo Firebase Hosting per ospitare il nostro codice e Firebase attiva il compressione gzip per impostazione predefinita, quindi, grazie all'hosting del nostro codice su una CDN ragionevole, abbiamo ottenuto questo vantaggio senza costi.
Sebbene gzip sia un metodo di compressione molto diffuso, anche altri meccanismi come Zopfli e Brotli stanno guadagnando popolarità. Brotli è supportato dalla maggior parte dei browser e puoi utilizzare un file binario per precomprimere gli asset prima di inviarli al server.
Utilizza criteri della cache efficaci
Il passaggio successivo è stato assicurarci di non inviare risorse due volte, se non necessario.
Il controllo Norme di cache inefficienti in Lighthouse ci ha aiutato a capire che potevamo ottimizzare le nostre strategie di memorizzazione nella cache per ottenere esattamente questo risultato. Impostando un'intestazione di scadenza max-age nel nostro server, ci siamo assicurati che, a seguito di una visita ripetuta, l'utente possa riutilizzare le risorse che ha scaricato in precedenza.
Idealmente, dovresti mirare a memorizzare nella cache il maggior numero possibile di risorse nel modo più sicuro possibile per il periodo di tempo più lungo possibile e fornire token di convalida per una convalida efficiente delle risorse aggiornate.
Rimuovi il codice inutilizzato
Finora abbiamo rimosso le parti evidenti del download non necessario, ma che dire di quelle meno evidenti? Ad esempio, codice inutilizzato.
A volte includiamo nelle nostre app codice non strettamente necessario. Questo accade soprattutto se lavori alla tua app per un periodo di tempo più lungo, se il tuo team o le tue dipendenze cambiano e a volte una libreria orfana viene lasciata indietro. È esattamente quello che è successo a noi.
All'inizio utilizzavamo la libreria Material Components per realizzare rapidamente un prototipo della nostra app. Con il tempo siamo passati a un aspetto più personalizzato e abbiamo dimenticato completamente questa libreria. Fortunatamente, il controllo della copertura del codice ci ha aiutato a ritrovarlo nel nostro bundle.
Puoi controllare le statistiche sulla copertura del codice in DevTools, sia per il runtime sia per il tempo di caricamento della tua applicazione. Puoi vedere le due grandi strisce rosse nello screenshot in basso: oltre il 95% del CSS non era utilizzato, così come una grande quantità di JavaScript.
Lighthouse ha rilevato questo problema anche nel controllo delle regole CSS inutilizzate. Ha mostrato un potenziale risparmio di oltre 400 KB. Quindi siamo tornati al nostro codice e abbiamo rimosso sia la parte JavaScript sia la parte CSS della libreria.
In questo modo, il nostro bundle CSS è stato ridotto di 20 volte, un buon risultato per un commit di due righe.
Naturalmente, il nostro punteggio di rendimento è aumentato e anche il tempo di risposta è migliorato notevolmente.
Tuttavia, con cambiamenti di questo tipo, non è sufficiente controllare solo le metriche e i punteggi. La rimozione del codice effettivo non è mai priva di rischi, quindi devi sempre fare attenzione a potenziali regressioni.
Il nostro codice non è stato utilizzato nel 95% dei casi, ma c'è ancora questo 5% da qualche parte. A quanto pare uno dei nostri componenti stava ancora utilizzando gli stili di quella libreria, ovvero le piccole frecce nel cursore del doodle. Tuttavia, poiché era così piccolo, abbiamo potuto incorporare manualmente questi stili nei pulsanti.
Pertanto, se rimuovi del codice, assicurati di avere implementato un workflow di test adeguato per proteggerti da potenziali regressioni visive.
Evita payload di rete enormi
Sappiamo che le risorse di grandi dimensioni possono rallentare il caricamento delle pagine web. Possono costare denaro ai nostri utenti e avere un grande impatto sui loro piani dati, quindi è molto importante tenerne conto.
Lighthouse è stato in grado di rilevare un problema con alcuni dei nostri payload di rete utilizzando il controllo Payload di rete enorme.
Abbiamo notato che il codice inviato era di oltre 3 MB, un volume piuttosto elevato, soprattutto sui dispositivi mobili.
Nella parte superiore di questo elenco, Lighthouse ha evidenziato che avevamo un bundle di fornitori JavaScript di 2 MB di codice non compresso. Si tratta anche di un problema evidenziato da webpack.
Come si suol dire, la richiesta più veloce è quella che non viene fatta.
Idealmente, dovresti misurare il valore di ogni singolo asset che offri agli utenti, misurarne le prestazioni e decidere se vale la pena implementarlo nell'esperienza iniziale. Perché a volte questi asset possono essere differiti, caricati in modo lazy o elaborati durante i tempi di inattività.
Nel nostro caso, poiché abbiamo a che fare con molti bundle JavaScript, abbiamo avuto la fortuna di avere a disposizione una vasta gamma di strumenti di controllo dei bundle JavaScript.
Abbiamo iniziato con webpack bundle analyzer, che ci ha comunicato che stavamo includendo una dipendenza chiamata unicode che occupava 1,6 MB di codice JavaScript analizzato, quindi parecchio.
Poi abbiamo utilizzato il plug-in per l'importazione dei costi per Visual Code nel nostro editor per visualizzare il costo di ogni modulo importato. In questo modo abbiamo scoperto quale componente includeva il codice che faceva riferimento a questo modulo.
Poi abbiamo passato a un altro strumento, BundlePhobia. Si tratta di uno strumento che ti consente di inserire il nome di qualsiasi pacchetto NPM e di visualizzare le dimensioni stimate in formato minimizzato e compresso con gzip. Abbiamo trovato una buona alternativa al modulo slug che stavamo utilizzando, che pesa solo 2,2 KB, quindi abbiamo effettuato il passaggio.
Ciò ha avuto un grande impatto sul nostro rendimento. Grazie a questa modifica e alla scoperta di altre opportunità per ridurre le dimensioni del bundle JavaScript, abbiamo risparmiato 2,1 MB di codice.
Abbiamo registrato un miglioramento complessivo del 65%, tenendo conto delle dimensioni compresse e minimizzate di questi pacchetti. e abbiamo scoperto che valeva davvero la pena farlo.
In generale, quindi, cerca di eliminare i download non necessari nei tuoi siti e nelle tue app. Eseguire un inventario delle risorse e misurarne l'impatto sul rendimento può fare la differenza, quindi assicurati di eseguire la revisione delle risorse abbastanza regolarmente.
Riduci il tempo di avvio di JavaScript con la suddivisione del codice
Sebbene i payload di rete di grandi dimensioni possano avere un grande impatto sulla nostra app, c'è un'altra cosa che può avere un impatto molto significativo: JavaScript.
JavaScript è la tua risorsa più costosa. Sui dispositivi mobili, se invii grandi bundle di JavaScript, l'interazione degli utenti con i componenti dell'interfaccia utente potrebbe essere ritardata. Ciò significa che possono toccare l'interfaccia utente senza che accada nulla di significativo. Per questo motivo, è importante capire perché JavaScript costa così tanto.
Questo è il modo in cui un browser elabora JavaScript.
Innanzitutto dobbiamo scaricare lo script, abbiamo un motore JavaScript che deve analizzare il codice, compilarlo ed eseguirlo.
Ora queste fasi non richiedono molto tempo su un dispositivo di fascia alta come un computer o un laptop, o forse anche uno smartphone di fascia alta. Tuttavia, su uno smartphone medio questo processo può richiedere da cinque a dieci volte più tempo. Questo è ciò che ritarda l'interattività, quindi è importante provare a ridurlo.
Per aiutarti a scoprire questi problemi con la tua app, abbiamo introdotto in Lighthouse un nuovo controllo del tempo di avvio di JavaScript.
Nel caso dell'app Oodle, ci è stato comunicato che il tempo impiegato per il caricamento di JavaScript è stato di 1,8 secondi. Il problema era che importavamo in modo statico tutti i nostri percorsi e componenti in un unico bundle JavaScript monolitico.
Una tecnica per aggirare il problema è utilizzare la suddivisione del codice.
La suddivisione del codice è l'idea di non dare agli utenti una pizza intera di JavaScript, ma di dare loro una fetta alla volta, in base alle loro esigenze.
La suddivisione del codice può essere applicata a livello di percorso o di componente. Funziona perfettamente con React e React Loadable, Vue.js, Angular, Polymer, Preact e molte altre librerie.
Abbiamo incorporato la suddivisione del codice nella nostra applicazione, passando dalle importazioni statiche alle importazioni dinamiche, il che ci ha permesso di caricare il codice in modo asincrono secondo le nostre esigenze.
Questo ha comportato una riduzione delle dimensioni dei bundle e del tempo di avvio di JavaScript. Il tempo è sceso a 0,78 secondi, rendendo l'app più veloce del 56%.
In generale, se stai creando un'esperienza basata su JavaScript, assicurati di inviare all'utente solo il codice di cui ha bisogno.
Sfrutta concetti come la suddivisione del codice, esplora idee come l'eliminazione degli elementi inutilizzati e dai un'occhiata al repo webpack-libs-optimizations per alcune idee su come ridurre le dimensioni della libreria se utilizzi webpack.
Ottimizza immagini
Nell'app Oodle utilizziamo molte immagini. Purtroppo, Lighthouse era molto meno entusiasta di noi. Infatti, non abbiamo superato tutti e tre i controlli relativi alle immagini.
Abbiamo dimenticato di ottimizzare le immagini, non ne regolavamo correttamente le dimensioni e avremmo potuto ottenere un guadagno dall'utilizzo di altri formati di immagini.
Abbiamo iniziato ottimizzando le nostre immagini.
Per un'ottimizzazione una tantum, puoi utilizzare strumenti visivi come ImageOptim o XNConvert.
Un approccio più automatizzato consiste nell'aggiungere un passaggio di ottimizzazione delle immagini al processo di compilazione, con librerie come imagemin.
In questo modo, le immagini aggiunte in futuro verranno ottimizzate automaticamente. Alcune CDN, ad esempio Akamai o soluzioni di terze parti come Cloudinary, Fastly o Uploadcare, offrono soluzioni complete per l'ottimizzazione delle immagini. Puoi anche semplicemente ospitare le tue immagini su questi servizi.
Se non vuoi farlo a causa del costo o di problemi di latenza, progetti come Thumbor o Imageflow offrono alternative self-hosted.
Il nostro PNG di sfondo è stato segnalato in webpack come di grandi dimensioni, e giustamente. Dopo averlo ridimensionato correttamente in base all'area visibile e averlo eseguito tramite ImageOptim, siamo scesi a 100 KB, un valore accettabile.
Ripetendo questa operazione per più immagini sul nostro sito, abbiamo potuto ridurre notevolmente il peso complessivo della pagina.
Utilizza il formato giusto per i contenuti animati
Le GIF possono essere molto costose. Sorprendentemente, il formato GIF non è mai stato concepito come piattaforma di animazione. Pertanto, il passaggio a un formato video più adatto ti consente di risparmiare notevolmente in termini di dimensioni del file.
Nell'app Oodle, utilizzavamo una GIF come sequenza introduttiva nella home page. Secondo Lighthouse, potremmo risparmiare oltre 7 MB passando a un formato video più efficiente. Il nostro clip pesava circa 7,3 MB, troppo per qualsiasi sito web ragionevole, quindi lo abbiamo trasformato in un elemento video con due file di origine: uno in formato MP4 e uno in formato WebM per un supporto più ampio dei browser.
Abbiamo utilizzato lo strumento FFmpeg per convertire la GIF animata in un file MP4. Il formato WebM ti offre risparmi ancora maggiori: l'API ImageOptim può eseguire questa conversione per te.
ffmpeg -i animation.gif -b:v 0 -crf 40 -vf scale=600:-1 video.mp4
Grazie a questa conversione, siamo riusciti a risparmiare oltre l'80% del peso complessivo. In questo modo abbiamo ridotto il volume a circa 1 MB.
Tuttavia, 1 MB è una risorsa di grandi dimensioni da inviare, soprattutto per un utente con una larghezza di banda limitata. Fortunatamente, possiamo utilizzare l'API Effective Type per capire che la larghezza di banda è bassa e fornire un JPEG molto più piccolo.
Questa interfaccia utilizza il tempo di percorrenza effettivo e i valori di interruzione per stimare il tipo di rete utilizzato dall'utente. Restituisce semplicemente una stringa, 2G lento, 2G, 3G o 4G. Pertanto, a seconda di questo valore, se l'utente utilizza una rete inferiore al 4G, potremmo sostituire l'elemento video con l'immagine.
if (navigator.connection.effectiveType) { ... }
L'esperienza ne risente un po', ma almeno il sito è utilizzabile su una connessione lenta.
Caricamento lento delle immagini fuori schermo
I caroselli, i cursori o le pagine molto lunghe caricano spesso immagini, anche se l'utente non può visualizzarle subito sulla pagina.
Lighthouse segnala questo comportamento nel controllo delle immagini off-screen e puoi anche visualizzarlo personalmente nel riquadro della rete di DevTools. Se noti che vengono caricate molte immagini, ma solo alcune sono visibili nella pagina, potresti prendere in considerazione il caricamento differito.
Il caricamento lento non è ancora supportato in modo nativo nel browser, quindi dobbiamo utilizzare JavaScript per aggiungere questa funzionalità. Abbiamo utilizzato la libreria Lazysizes per aggiungere il comportamento di caricamento lazy alle nostre copertine Oodle.
<!-- Import library -->
import lazysizes from 'lazysizes' <!-- or -->
<script src="lazysizes.min.js"></script>
<!-- Use it -->
<img data-src="image.jpg" class="lazyload"/>
<img class="lazyload"
data-sizes="auto"
data-src="image2.jpg"
data-srcset="image1.jpg 300w,
image2.jpg 600w,
image3.jpg 900w"/>
Lazysizes è intelligente perché non solo monitora le modifiche alla visibilità dell'elemento, ma precompila anche in modo proattivo gli elementi vicini alla visualizzazione per un'esperienza utente ottimale.
Offre inoltre un'integrazione facoltativa del IntersectionObserver
, che consente ricerche di visibilità molto efficaci.
Dopo questa modifica, le nostre immagini vengono recuperate su richiesta. Per approfondire questo argomento, consulta images.guide, una risorsa molto utile e completa.
Aiuta il browser a fornire in anticipo le risorse fondamentali
Non tutti i byte inviati al browser hanno lo stesso grado di importanza e il browser lo sa. Molti browser hanno metodi di euristica per decidere cosa recuperare per primo. Pertanto, a volte recuperano il CSS prima delle immagini o degli script.
Un'idea che potrebbe essere utile è che noi, in qualità di autori della pagina, comunichiamo al browser ciò che è davvero importante per noi. Fortunatamente, negli ultimi due anni i fornitori di browser hanno aggiunto una serie di funzionalità per aiutarci, ad esempio i suggerimenti sulle risorse come link rel=preconnect
, preload
o prefetch
.
Queste funzionalità introdotte nella piattaforma web aiutano il browser a recuperare l'elemento corretto al momento giusto e possono essere un po' più efficienti di alcuni approcci basati su logica e caricamento personalizzato che vengono eseguiti utilizzando script.
Vediamo in che modo Lighthouse ci aiuta a utilizzare alcune di queste funzionalità in modo efficace.
La prima cosa che Lighthouse ci dice di fare è evitare più viaggi di andata e ritorno costosi verso qualsiasi origine.
Nel caso dell'app Oodle, utilizziamo molto Google Fonts. Ogni volta che inserisci un stylesheet di Google Font nella pagina, verrà collegato a un massimo di due sottodomini. Lighthouse ci dice che se riuscissimo a eseguire l'inizializzazione della connessione, potremmo risparmiare fino a 300 millisecondi nel tempo di connessione iniziale.
Sfruttando il preconnect dei link rel, possiamo mascherare efficacemente la latenza di connessione.
Soprattutto con qualcosa come Google Fonts, dove il CSS dei nostri caratteri è ospitato su googleapis.com e le nostre risorse dei caratteri sono ospitate su Gstatic, questo può avere un impatto molto elevato. Abbiamo quindi applicato questa ottimizzazione e abbiamo risparmiato alcune centinaia di millisecondi.
Lighthouse suggerisce di precaricare le richieste chiave.
<link rel=preload>
è molto potente, informa il browser che è necessaria una risorsa nell'ambito della navigazione corrente e tenta di far sì che il browser la recuperi il prima possibile.
Lighthouse ci dice che dobbiamo precaricare le risorse dei caratteri web principali perché stiamo caricando due caratteri web.
Il precaricamento in un carattere web è il seguente: specificando rel=preload
, passi as
con il tipo di carattere, quindi specifichi il tipo di carattere che stai tentando di caricare, ad esempio woff2.
L'impatto che questo può avere sulla tua pagina è piuttosto netto.
Normalmente, senza utilizzare il precaricamento dei link rel, se i caratteri web sono fondamentali per la tua pagina, il browser deve prima recuperare il codice HTML, analizzare il codice CSS e, molto più avanti, recuperare i caratteri web.
Con il precaricamento dei link rel, non appena il browser ha analizzato il codice HTML, può iniziare a recuperare i caratteri web molto prima. Nel caso della nostra app, è stato possibile risparmiare un secondo sul tempo necessario per il rendering del testo utilizzando i nostri caratteri web.
Ora non è così semplice se vuoi provare a precaricare i caratteri utilizzando Google Fonts, c'è un problema.
Gli URL dei caratteri Google che specifichiamo nei nostri stili di carattere sono stati aggiornati abbastanza regolarmente dal team dei caratteri. Questi URL possono scadere o essere aggiornati con frequenza regolare, pertanto ti consigliamo di ospitare autonomamente i tuoi caratteri web se vuoi avere il controllo completo sull'esperienza di caricamento dei caratteri. Questo può essere molto utile perché ti consente di accedere ad elementi come il precaricamento dei link rel.
Nel nostro caso, abbiamo trovato lo strumento Google Web Fonts Helper molto utile per scaricare alcuni di questi caratteri web e configurarli localmente, quindi dai un'occhiata.
Che tu stia utilizzando caratteri web come parte delle risorse fondamentali o che si tratti di JavaScript, prova ad aiutare il browser a caricare le risorse fondamentali il prima possibile.
(Sperimentale) Suggerimenti di priorità
Oggi abbiamo qualcosa di speciale da condividere con te. Oltre a funzionalità come gli hint delle risorse e il precaricamento, stiamo lavorando a una nuova funzionalità sperimentale del browser chiamata hint di priorità.
Si tratta di una nuova funzionalità che consente di suggerire al browser l'importanza di una risorsa. Espone un nuovo attributo, importance, con i valori low, high o auto.
In questo modo possiamo ridurre la priorità delle risorse meno importanti, come stili, immagini o chiamate API non critici, per ridurre le contese. Possiamo anche aumentare la priorità di elementi più importanti, come le nostre immagini hero.
Nel caso della nostra app Oodle, questo ci ha permesso di individuare un punto pratico in cui effettuare l'ottimizzazione.
Prima di aggiungere il caricamento differito alle nostre immagini, il browser caricava questo carosello di immagini con tutti i nostri scarabocchi e recuperava tutte le immagini all'inizio del carosello con una priorità elevata. Purtroppo, le immagini al centro del carosello erano le più importanti per l'utente. Abbiamo impostato l'importanza delle immagini di sfondo su molto bassa e quelle in primo piano su molto alta. Il risultato è stato un impatto di due secondi su una rete 3G lenta e sulla velocità con cui siamo riusciti a recuperare e visualizzare queste immagini. Quindi un'esperienza positiva.
Ci auguriamo di poter rendere disponibile questa funzionalità in Canary tra qualche settimana, quindi tieni d'occhio gli aggiornamenti.
Avere una strategia di caricamento dei caratteri web
La tipografia è fondamentale per un buon design e, se utilizzi i caratteri web, idealmente non vuoi bloccare il rendering del testo e di certo non vuoi mostrare testo invisibile.
Ora lo evidenziamo in Lighthouse, con il controllo Evita il testo invisibile durante il caricamento dei caratteri web.
Se carichi i caratteri web utilizzando un blocco di caratteri, lasci che sia il browser a decidere cosa fare se il recupero del carattere web richiede molto tempo. Alcuni browser attenderanno fino a tre secondi prima di passare a un carattere di sistema e alla fine lo sostituiranno con il carattere scaricato.
Stiamo cercando di evitare questo testo invisibile, quindi in questo caso non avremmo potuto vedere i doodle classici di questa settimana se il carattere web avesse impiegato troppo tempo. Fortunatamente, con una nuova funzionalità chiamata
font-display
, hai un controllo molto maggiore su questa procedura.
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-display: swap;
font-weight: 400;
src: local('Montserrat Regular'), local('Montserrat-Regular'),
/* Chrome 26+, Opera 23+, Firefox 39+ */
url('montserrat-v12-latin-regular.woff2') format('woff2'),
/* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
url('montserrat-v12-latin-regular.woff') format('woff');
}
La visualizzazione dei caratteri ti consente di decidere come verranno visualizzati o come verrà eseguito il fallback dei caratteri web in base al tempo necessario per il loro scambio.
In questo caso utilizziamo lo scambio di visualizzazione dei caratteri. Lo scambio assegna al carattere un periodo di blocco di zero secondi e un periodo di scambio infinito. Ciò significa che il browser disegnerà il testo quasi immediatamente con un carattere di riserva se il caricamento del carattere richiede un po' di tempo. E lo sostituirà non appena il carattere sarà disponibile.
Nel caso della nostra app, è stato fantastico perché ci ha permesso di visualizzare un testo significativo molto presto e di passare al carattere web quando era pronto.
In generale, se utilizzi i caratteri web, come fa una grande percentuale di siti web, adotta una buona strategia di caricamento dei caratteri web.
Esistono molte funzionalità della piattaforma web che puoi utilizzare per ottimizzare l'esperienza di caricamento dei caratteri, ma dai un'occhiata anche al repo Web Font Recipes di Zach Leatherman, perché è davvero fantastico.
Riduci gli script che bloccano la visualizzazione
Esistono altre parti della nostra applicazione che potremmo spingere prima nella catena di download per fornire almeno un'esperienza utente di base un po' prima.
Nella barra della sequenza temporale di Lighthouse puoi vedere che durante questi primi secondi, quando tutte le risorse vengono caricate, l'utente non può vedere alcun contenuto.
Il download e l'elaborazione di fogli di stile esterni stanno bloccando il nostro processo di rendering.
Possiamo provare a ottimizzare il percorso di rendering critico caricando alcuni stili un po' prima.
Se estraiamo gli stili responsabili di questo rendering iniziale e li inseriamo in linea nel codice HTML, il browser è in grado di visualizzarli immediatamente senza attendere l'arrivo dei fogli di stile esterni.
Nel nostro caso, abbiamo utilizzato un modulo NPM denominato Critical per incorporare i contenuti critici in index.html durante un passaggio di compilazione.
Anche se questo modulo ha svolto la maggior parte del lavoro per noi, è stato comunque un po' complicato farlo funzionare senza problemi su percorsi diversi.
Se non fai attenzione o la struttura del tuo sito è molto complessa, potrebbe essere molto difficile inserire questo tipo di pattern se non hai pianificato l'architettura dell'app shell fin dall'inizio.
Ecco perché è così importante prendere in considerazione il rendimento fin dall'inizio. Se non progetti per il rendimento fin dall'inizio, è molto probabile che tu abbia problemi in un secondo momento.
Alla fine il rischio è stato ripagato, siamo riusciti a farlo funzionare e l'app ha iniziato a pubblicare i contenuti molto prima, migliorando notevolmente il nostro primo tempo di visualizzazione significativo.
Il risultato
Questo è un lungo elenco di ottimizzazioni del rendimento che abbiamo applicato al nostro sito. Diamo un'occhiata al risultato. Questo è il modo in cui la nostra app è stata caricata su un dispositivo mobile di medie dimensioni su una rete 3G, prima e dopo l'ottimizzazione.
Il punteggio relativo alle prestazioni di Lighthouse è aumentato da 23 a 91. Ottimi progressi in termini di velocità. Tutte le modifiche sono state apportate grazie al controllo e all'applicazione continua del report Lighthouse. Se vuoi scoprire come abbiamo implementato tecnicamente tutti i miglioramenti, dai un'occhiata al nostro repository, in particolare alle PR che sono state caricate al suo interno.
Rendimento predittivo: esperienze utente basate sui dati
Riteniamo che il machine learning rappresenti un'opportunità entusiasmante per il futuro in molti settori. Un'idea che ci auguriamo possa stimolare ulteriori sperimentazioni in futuro è che i dati reali possono davvero guidare le esperienze utente che stiamo creando.
Oggi prendiamo molte decisioni arbitrarie su ciò che l'utente potrebbe volere o di cui potrebbe avere bisogno e, di conseguenza, su cosa vale la pena prelevare, precaricare o memorizzare nella cache. Se indoviniamo, possiamo dare la priorità a una piccola quantità di risorse, ma è molto difficile scalare l'intero sito web.
Al momento abbiamo a disposizione dati per migliorare le nostre ottimizzazioni. Con l'API di reporting di Google Analytics, possiamo esaminare la pagina successiva più visitata e le percentuali di uscita per qualsiasi URL sul nostro sito e trarre conclusioni sulle risorse da dare la priorità.
Se combiniamo questo approccio con un buon modello di probabilità, evitiamo di sprecare i dati dei nostri utenti eseguendo un over-prefetch aggressivo dei contenuti. Possiamo sfruttare i dati di Google Analytics e utilizzare il machine learning e modelli come le catene di Markov o le reti neurali per implementare questi modelli.
Per semplificare questi esperimenti, siamo lieti di annunciare una nuova iniziativa chiamata Guess.js.
Guess.js è un progetto incentrato su esperienze utente basate sui dati per il web. Ci auguriamo che stimoli l'esplorazione dell'utilizzo dei dati per migliorare il rendimento del web e non solo. È tutto open source e disponibile su GitHub oggi. È stato creato in collaborazione con la community open source da Minko Gechev, Kyle Matthews di Gatsby, Katie Hempenius e altri.
Dai un'occhiata a Guess.js e facci sapere cosa ne pensi.
Riepilogo
I punteggi e le metriche sono utili per migliorare la velocità del web, ma sono solo i mezzi, non gli obiettivi stessi.
Tutti abbiamo riscontrato caricamenti lenti delle pagine quando siamo in movimento, ma ora abbiamo l'opportunità di offrire ai nostri utenti esperienze più piacevoli che si caricano molto rapidamente.
Migliorare il rendimento è un percorso. Molti piccoli cambiamenti possono portare a grandi risultati. Utilizzando gli strumenti di ottimizzazione giusti e tenendo d'occhio i report Lighthouse, puoi offrire ai tuoi utenti un'esperienza migliore e più inclusiva.
Un ringraziamento speciale a: Ward Peeters, Minko Gechev, Kyle Mathews, Katie Hempenius, Dom Farolino, Yoav Weiss, Susie Lu, Yusuke Utsunomiya, Tom Ankers, Lighthouse e Google Doodles.