Come abbiamo migliorato i nostri elementi vitali Web principali (caso di studio)
Pubblicato: 2022-03-10L'anno scorso, Google ha iniziato a sottolineare l'importanza dei Core Web Vitals e il modo in cui riflettono l'esperienza reale di una persona quando visita i siti sul Web. Le prestazioni sono una caratteristica fondamentale della nostra azienda, Instant Domain Search, è nel nome. Immagina la nostra sorpresa quando abbiamo scoperto che i nostri punteggi vitali non erano ottimi per molte persone. I nostri computer veloci e Internet in fibra hanno mascherato l'esperienza che le persone reali hanno sul nostro sito. Non passò molto tempo prima che un mare di avvisi rossi "poveri" e gialli "deve essere migliorato" nella nostra Console di ricerca di Google richiedesse la nostra attenzione. L'entropia aveva vinto e dovevamo capire come ripulire il jank e rendere il nostro sito più veloce.
Ho fondato Instant Domain Search nel 2005 e l'ho mantenuto come un trambusto secondario mentre lavoravo in una società Y Combinator (Snipshot, W06), prima di lavorare come ingegnere del software su Facebook. Di recente siamo diventati un piccolo gruppo con sede principalmente a Victoria, in Canada, e stiamo lavorando su un lungo arretrato di nuove funzionalità e miglioramenti delle prestazioni. I nostri scarsi punteggi web vitals e l'imminente aggiornamento di Google hanno portato la nostra attenzione alla ricerca e alla risoluzione di questi problemi.
Quando è stata lanciata la prima versione del sito, l'avevo creata con PHP, MySQL e XMLHttpRequest. Internet Explorer 6 era completamente supportato, Firefox stava guadagnando quote e Chrome era ancora a distanza di anni dal lancio. Nel tempo, ci siamo evoluti attraverso una varietà di generatori di siti statici, framework JavaScript e tecnologie server. Il nostro attuale stack front-end è React servito con Next.js e un servizio di back-end integrato Rust per rispondere alle nostre ricerche di nomi di dominio. Cerchiamo di seguire le migliori pratiche servendo il più possibile su una CDN, evitando il maggior numero possibile di script di terze parti e utilizzando semplici grafici SVG invece di PNG bitmap. Non era abbastanza.
Next.js ci consente di creare le nostre pagine e componenti in React e TypeScript. Se abbinato a VS Code, l'esperienza di sviluppo è sorprendente. Next.js generalmente funziona trasformando i componenti React in HTML e CSS statici. In questo modo, il contenuto iniziale può essere servito da una CDN, quindi Next può "idratare" la pagina per rendere dinamici gli elementi. Una volta che la pagina è idratata, il nostro sito si trasforma in un'app a pagina singola in cui le persone possono cercare e generare nomi di dominio. Non ci affidiamo a Next.js per fare molto lavoro lato server, la maggior parte dei nostri contenuti viene esportata staticamente come HTML, CSS e JavaScript per essere serviti da una CDN.
Quando qualcuno inizia a cercare un nome di dominio, sostituiamo il contenuto della pagina con i risultati della ricerca. Per rendere le ricerche il più veloci possibile, il front-end interroga direttamente il nostro backend Rust, che è fortemente ottimizzato per ricerche e suggerimenti di domini. A molte domande possiamo rispondere all'istante, ma per alcuni TLD è necessario eseguire query DNS più lente che possono richiedere uno o due secondi per essere risolte. Quando alcune di queste query più lente vengono risolte, aggiorneremo l'interfaccia utente con tutte le nuove informazioni in arrivo. Le pagine dei risultati sono diverse per tutti e può essere difficile per noi prevedere esattamente come ogni persona vive il sito.
I Chrome DevTools sono eccellenti e un buon punto di partenza quando si cercano problemi di prestazioni. La visualizzazione delle prestazioni mostra esattamente quando escono le richieste HTTP, dove il browser trascorre il tempo a valutare JavaScript e altro:
Ci sono tre metriche di Core Web Vitals che Google utilizzerà per aiutare a classificare i siti nel loro prossimo aggiornamento dell'algoritmo di ricerca. Google raggruppa le esperienze in "Buono", "Richiede miglioramenti" e "Scarso" in base ai punteggi LCP, FID e CLS che le persone reali hanno sul sito:
- LCP , o Largest Contentful Paint, definisce il tempo necessario affinché l'elemento di contenuto più grande diventi visibile.
- FID , o First Input Delay, si riferisce alla reattività di un sito all'interazione: il tempo che intercorre tra un tocco, un clic o la pressione di un tasto nell'interfaccia e la risposta dalla pagina.
- CLS , o Cumulative Layout Shift, tiene traccia di come gli elementi si spostano o si spostano sulla pagina in assenza di azioni come una tastiera o un evento di clic.
Chrome è impostato per tenere traccia di queste metriche su tutti gli utenti Chrome che hanno effettuato l'accesso e invia a Google statistiche anonime che riassumono l'esperienza di un cliente su un sito per la valutazione. Questi punteggi sono accessibili tramite il rapporto sull'esperienza utente di Chrome e vengono visualizzati quando controlli un URL con lo strumento PageSpeed Insights. I punteggi rappresentano il 75° percentile di esperienza per le persone che hanno visitato quell'URL nei 28 giorni precedenti. Questo è il numero che utilizzeranno per classificare i siti nell'aggiornamento.
Una metrica del 75° percentile (p75) raggiunge un ragionevole equilibrio per gli obiettivi di rendimento. Prendere una media, ad esempio, nasconderebbe molte brutte esperienze che le persone hanno. La mediana, o 50° percentile (p50), significherebbe che metà delle persone che utilizzano il nostro prodotto hanno avuto un'esperienza peggiore. Il 95° percentile (p95), d'altra parte, è difficile da costruire poiché cattura troppi valori anomali estremi su vecchi dispositivi con connessioni irregolari. Riteniamo che il punteggio basato sul 75° percentile sia uno standard equo da soddisfare.
Per tenere sotto controllo i nostri punteggi, ci siamo rivolti prima a Lighthouse per alcuni eccellenti strumenti integrati in Chrome e ospitati su web.dev/measure/ e su PageSpeed Insights. Questi strumenti ci hanno aiutato a trovare alcuni ampi problemi tecnici con il nostro sito. Abbiamo visto che il modo in cui Next.js raggruppava il nostro CSS e rallentava il nostro tempo di rendering iniziale che influiva sul nostro FID. La prima vittoria facile è arrivata da una funzionalità sperimentale di Next.js, optimizationCss, che ha contribuito a migliorare significativamente il nostro punteggio di prestazione generale.
Lighthouse ha anche rilevato un'errata configurazione della cache che impediva ad alcune delle nostre risorse statiche di essere servite dalla nostra CDN. Siamo ospitati su Google Cloud Platform e Google Cloud CDN richiede che l'intestazione Cache-Control contenga "pubblico". Next.js non ti consente di configurare tutte le intestazioni che emette, quindi abbiamo dovuto sovrascriverle posizionando il server Next.js dietro Caddy, un server proxy HTTP leggero implementato in Go. Abbiamo anche colto l'occasione per assicurarci di servire ciò che potevamo con il supporto relativamente nuovo e non aggiornato nei browser moderni che consente alla CDN di recuperare il contenuto dall'origine (il nostro server Next.js) in modo asincrono in background.
È facile, forse troppo facile, aggiungere quasi tutto ciò di cui hai bisogno al tuo prodotto da npm. Non ci vuole molto perché le dimensioni del pacco crescano. I pacchetti di grandi dimensioni richiedono più tempo per il download su reti lente e il telefono cellulare al 75° percentile impiegherà molto tempo a bloccare il thread dell'interfaccia utente principale mentre cerca di dare un senso a tutto il codice appena scaricato. Ci è piaciuto BundlePhobia, uno strumento gratuito che mostra quante dipendenze e quanti byte un pacchetto npm aggiungerà al tuo pacchetto. Questo ci ha portato a eliminare o sostituire una serie di animazioni a molla reattiva con transizioni CSS più semplici:
Attraverso l'uso di BundlePhobia e Lighthouse, abbiamo riscontrato che il software di analisi e registrazione degli errori di terze parti ha contribuito in modo significativo alle dimensioni del pacchetto e al tempo di caricamento. Abbiamo rimosso e sostituito questi strumenti con la nostra registrazione lato client che sfrutta le moderne API del browser come sendBeacon e ping. Inviamo la registrazione e l'analisi alla nostra infrastruttura Google BigQuery, dove possiamo rispondere alle domande che ci interessano in modo più dettagliato di quanto potrebbe fornire qualsiasi strumento standard. Questo elimina anche una serie di cookie di terze parti e ci offre un controllo molto maggiore su come e quando inviamo i dati di registrazione dai clienti.
Il nostro punteggio CLS aveva ancora più margini di miglioramento. Il modo in cui Google calcola il CLS è complicato: ti viene assegnata una "finestra di sessione" massima con un intervallo di 1 secondo, limitato a 5 secondi dal caricamento della pagina iniziale, o da una tastiera o da un'interazione di clic, per finire di spostare le cose nel sito . Se sei interessato a leggere più approfonditamente questo argomento, ecco un'ottima guida sull'argomento. Questo penalizza molti tipi di overlay e popup che appaiono subito dopo l'atterraggio su un sito. Ad esempio, annunci che spostano i contenuti o effettuano aumenti di vendite che potrebbero essere visualizzati quando inizi a scorrere gli annunci oltre per raggiungere i contenuti. Questo articolo fornisce un'eccellente spiegazione di come viene calcolato il punteggio CLS e del ragionamento alla base.
Siamo fondamentalmente contrari a questo tipo di disordine digitale, quindi siamo rimasti sorpresi di vedere quanto spazio di miglioramento Google ha insistito per fare. Chrome ha un overlay Web Vitals integrato a cui puoi accedere utilizzando il menu dei comandi per "Mostra overlay Web Vitals di base". Per vedere esattamente quali elementi Chrome considera nel suo calcolo CLS, abbiamo trovato più utile l'opzione "Registrazione console" dell'estensione Chrome Web Vitals nelle impostazioni. Una volta abilitato, questo plugin mostra i tuoi punteggi LCP, FID e CLS per la pagina corrente. Dalla console puoi vedere esattamente quali elementi della pagina sono collegati a questi punteggi. I nostri punteggi CLS avevano più margini di miglioramento.
Delle tre metriche, CLS è l'unica che si accumula quando interagisci con una pagina. L'estensione Web Vitals ha un'opzione di registrazione che mostrerà esattamente quali elementi causano CLS durante l'interazione con un prodotto. Guarda come si aggiungono le metriche CLS quando scorriamo sulla home page di Smashing Magazine:
Google continuerà a modificare il modo in cui calcola il CLS nel tempo, quindi è importante tenersi informati seguendo il blog di sviluppo web di Google. Quando si utilizzano strumenti come l'estensione Chrome Web Vitals, è importante abilitare la limitazione della CPU e della rete per ottenere un'esperienza più realistica. Puoi farlo con gli strumenti di sviluppo simulando una CPU mobile.
Il modo migliore per monitorare i progressi da una distribuzione all'altra è misurare le esperienze delle pagine allo stesso modo di Google. Se hai configurato Google Analytics, un modo semplice per farlo è installare il modulo web-vitals di Google e collegarlo a Google Analytics. Ciò fornisce una misura approssimativa dei tuoi progressi e lo rende visibile in una dashboard di Google Analytics.
Qui è dove abbiamo colpito un muro. Abbiamo potuto vedere il nostro punteggio CLS e, sebbene lo avessimo migliorato in modo significativo, avevamo ancora del lavoro da fare. Il nostro punteggio CLS era di circa 0,23 e dovevamo portarlo al di sotto di 0,1, e preferibilmente fino a 0. A questo punto, tuttavia, non siamo riusciti a trovare qualcosa che ci dicesse esattamente quali componenti su quali pagine stavano ancora influenzando il punteggio. Abbiamo potuto vedere che Chrome ha esposto molti dettagli nei loro strumenti Core Web Vitals, ma che gli aggregatori di registrazione hanno buttato via la parte più importante: esattamente quale elemento della pagina ha causato il problema.
Per acquisire tutti i dettagli di cui abbiamo bisogno, abbiamo creato una funzione serverless per acquisire dati vitali web dai browser. Poiché non è necessario eseguire query in tempo reale sui dati, li trasmettiamo nell'API di streaming di Google BigQuery per l'archiviazione. Questa architettura significa che possiamo acquisire a buon mercato tutti i punti dati che possiamo generare.
Dopo aver appreso alcune lezioni lavorando con Web Vitals e BigQuery, abbiamo deciso di raggruppare questa funzionalità e rilasciare questi strumenti come open-source su vitals.dev.
L'utilizzo di Instant Vitals è un modo rapido per iniziare a monitorare i punteggi di Web Vitals in BigQuery. Ecco un esempio di schema di una tabella BigQuery che creiamo:
L'integrazione con Instant Vitals è facile. Puoi iniziare integrandoti con la libreria client per inviare dati alla tua funzione back-end o serverless:
import { init } from "@instantdomain/vitals-client"; init({ endpoint: "/api/web-vitals" });
Quindi, sul tuo server, puoi integrarti con la libreria del server per completare il circuito:
import fs from "fs"; import { init, streamVitals } from "@instantdomain/vitals-server"; // Google libraries require service key as path to file const GOOGLE_SERVICE_KEY = process.env.GOOGLE_SERVICE_KEY; process.env.GOOGLE_APPLICATION_CREDENTIALS = "/tmp/goog_creds"; fs.writeFileSync( process.env.GOOGLE_APPLICATION_CREDENTIALS, GOOGLE_SERVICE_KEY ); const DATASET_; init({ datasetId: DATASET_ID }).then().catch(console.error); // Request handler export default async (req, res) => { const body = JSON.parse(req.body); await streamVitals(body, body.name); res.status(200).end(); };
Chiama semplicemente streamVitals
con il corpo della richiesta e il nome della metrica per inviare la metrica a BigQuery. La libreria gestirà la creazione del set di dati e delle tabelle per te.
Dopo aver raccolto un giorno di dati, abbiamo eseguito questa query come questa:
SELECT `<project_name>.web_vitals.CLS`.Value, Node FROM `<project_name>.web_vitals.CLS` JOIN UNNEST(Entries) AS Entry JOIN UNNEST(Entry.Sources) WHERE Node != "" ORDER BY value LIMIT 10
Questa query produce risultati come questo:
Valore | Nodo |
---|---|
4.6045324800736724E-4 | /html/body/div[1]/main/div/div/div[2]/div/div/blockquote |
7.183070668914928E-4 | /html/body/div[1]/header/div/div/header/div |
0.031002668277977697 | /html/body/div[1]/footer |
0.035830703317463526 | /html/body/div[1]/main/div/div/div[2] |
0.035830703317463526 | /html/body/div[1]/footer |
0.035830703317463526 | /html/body/div[1]/main/div/div/div[2] |
0.035830703317463526 | /html/body/div[1]/main/div/div/div[2] |
0.035830703317463526 | /html/body/div[1]/footer |
0.035830703317463526 | /html/body/div[1]/footer |
0.03988482067913317 | /html/body/div[1]/footer |
Questo ci mostra quali elementi su quali pagine hanno il maggiore impatto su CLS. Ha creato una lista di pugno che il nostro team può indagare e correggere. Su Instant Domain Search, risulta che connessioni mobili lente o scadenti impiegheranno più di 500 ms per caricare alcuni dei nostri risultati di ricerca. Uno dei peggiori contributi a CLS per questi utenti è stato in realtà il nostro footer.
Il punteggio di spostamento del layout viene calcolato in funzione della dimensione dell'elemento in movimento e di quanto lontano si spinge. Nella nostra visualizzazione dei risultati di ricerca, se un dispositivo impiega più di una certa quantità di tempo per ricevere e visualizzare i risultati della ricerca, la visualizzazione dei risultati si comprime a zero-height
, visualizzando il piè di pagina. Quando i risultati arrivano, riportano il piè di pagina in fondo alla pagina. Un grande elemento DOM che si è spostato così lontano ha aggiunto molto al nostro punteggio CLS. Per risolverlo correttamente, dobbiamo ristrutturare il modo in cui i risultati della ricerca vengono raccolti e visualizzati. Abbiamo deciso di rimuovere semplicemente il piè di pagina nella visualizzazione dei risultati di ricerca come un rapido hack che gli impedirebbe di rimbalzare su connessioni lente.
Ora esaminiamo questo rapporto regolarmente per tenere traccia di come stiamo migliorando e lo utilizziamo per combattere il calo dei risultati mentre avanziamo. Abbiamo assistito al valore di una maggiore attenzione alle funzionalità e ai prodotti lanciati di recente sul nostro sito e abbiamo operato controlli coerenti per assicurarci che i principali elementi vitali agiscano a favore della nostra classifica. Ci auguriamo che condividendo Instant Vitals possiamo aiutare anche altri sviluppatori ad affrontare i loro punteggi di Core Web Vitals.
Google fornisce eccellenti strumenti per le prestazioni integrati in Chrome e li abbiamo usati per trovare e risolvere una serie di problemi di prestazioni. Abbiamo appreso che i dati sul campo forniti da Google offrivano un buon riepilogo dei nostri progressi su p75, ma non avevano dettagli utilizzabili. Dovevamo scoprire esattamente quali elementi DOM stavano causando cambiamenti di layout e ritardi di input. Una volta che abbiamo iniziato a raccogliere i nostri dati sul campo, con le query XPath, siamo stati in grado di identificare opportunità specifiche per migliorare l'esperienza di tutti sul nostro sito. Con un po' di sforzo, abbiamo ridotto i punteggi del nostro campo di Core Web Vitals nel mondo reale in un intervallo accettabile in preparazione per l'aggiornamento dell'esperienza della pagina di giugno. Siamo felici di vedere questi numeri andare in basso e a destra!