Risoluzione dei problemi CLS in un sito Web di e-commerce basato su Next.js (caso di studio)
Pubblicato: 2022-03-10Fairprice è uno dei più grandi negozi di alimentari online di Singapore. Siamo costantemente alla ricerca di aree di opportunità per migliorare l'esperienza di acquisto online dell'utente. Le prestazioni sono uno degli aspetti fondamentali per garantire ai nostri utenti un'esperienza utente piacevole indipendentemente dai loro dispositivi o dalla connessione di rete.
Esistono molti indicatori chiave di prestazione (KPI) che misurano punti diversi durante il ciclo di vita della pagina Web (come TTFB, domInteractive
e onload
), ma queste metriche non riflettono il modo in cui l'utente finale sperimenta la pagina.
Volevamo utilizzare alcuni KPI che corrispondono strettamente all'esperienza effettiva degli utenti finali, quindi sappiamo che se qualcuno di questi KPI non funziona bene, avrà un impatto diretto sull'esperienza dell'utente finale. Abbiamo scoperto che le metriche delle prestazioni incentrate sull'utente si adattano perfettamente a questo scopo.
Esistono molte metriche delle prestazioni incentrate sull'utente per misurare diversi punti nel ciclo di vita di una pagina come FCP, LCP, FID, CLS e così via. Per questo caso di studio, ci concentreremo principalmente su CLS.
CLS misura il punteggio totale di tutti i cambiamenti di layout imprevisti che si verificano tra l'inizio del caricamento della pagina e lo scarico.
“
Pertanto, avere un valore CLS basso per una pagina assicura che non ci siano spostamenti casuali del layout che causano frustrazione all'utente. Barry Pollard ha scritto un eccellente articolo di approfondimento su CLS.
Come abbiamo scoperto il problema CLS nella nostra pagina del prodotto
Utilizziamo Lighthouse e WebPagetest come strumenti di test sintetici per misurare le prestazioni del CLS. Utilizziamo anche la libreria web-vitals per misurare i CLS per utenti reali. A parte questo, controlliamo la sezione Report sui vitali web principali di Google Search Console per avere un'idea di eventuali problemi di CLS in una qualsiasi delle nostre pagine. Durante l'esplorazione della sezione del rapporto, abbiamo riscontrato che molti URL della pagina dei dettagli del prodotto avevano un valore CLS superiore a 0,1 , il che suggerisce che si è verificato un importante evento di cambiamento del layout.
Debug del problema CLS utilizzando strumenti diversi
Ora che sappiamo che c'è un problema CLS nella pagina dei dettagli del prodotto, il passaggio successivo è stato identificare quale elemento lo causava. Inizialmente, abbiamo deciso di eseguire alcuni test utilizzando strumenti di test sintetici.
Quindi abbiamo eseguito il faro per verificare se poteva trovare qualsiasi elemento che potesse innescare un importante cambiamento di layout, ha riportato CLS a .004 che è piuttosto basso.
La pagina del rapporto del faro ha una sezione diagnostica. Anche questo non ha mostrato alcun elemento che causasse un valore CLS elevato.
Quindi abbiamo eseguito WebpageTest e abbiamo deciso di controllare la visualizzazione della sequenza:
Troviamo questa funzione molto utile poiché possiamo scoprire quale elemento in quel momento ha causato lo spostamento del layout. Ma quando eseguiamo il test per vedere se vengono evidenziati eventuali cambiamenti di layout, non c'era nulla che contribuisse all'enorme LCS:
La particolarità di CLS è che registra i singoli punteggi di spostamento del layout durante l'intera durata della pagina e li aggiunge.
“
Nota : la modalità di misurazione del CLS è stata modificata da giugno 2021.
Poiché Lighthouse e WebpageTest non sono stati in grado di rilevare alcun elemento che abbia attivato un importante cambiamento di layout, il che significa che si stava verificando dopo il caricamento della pagina iniziale, probabilmente a causa di alcune azioni dell'utente. Quindi abbiamo deciso di utilizzare l'estensione Google Chrome di Web Vitals poiché può registrare CLS su una pagina mentre l'utente interagisce con essa. Dopo aver eseguito diverse azioni, abbiamo riscontrato che il punteggio di spostamento del layout aumenta quando l'utente utilizza la funzione di ingrandimento dell'immagine.
Per verificare in modo incrociato se si verifica uno spostamento del layout mentre il passaggio del mouse è sull'immagine, abbiamo utilizzato il frammento di codice seguente da https://web.dev/cls/ che aggiunge console.log
quando si verifica lo spostamento del layout:
let cls = 0; new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { if (!entry.hadRecentInput) { cls += entry.value; console.log('Current CLS value:', cls, entry); } }}).observe({type: 'layout-shift', buffered: true});
Dopo ulteriori indagini, abbiamo scoperto che ASDA ha affrontato un tipo simile di problema e l'ha sollevato per il cromo.
Causa ultima
Nella pagina dei dettagli del prodotto, gli utenti possono spostare il mouse sull'immagine del prodotto per visualizzare una sezione ingrandita dell'immagine accanto all'immagine del prodotto reale poiché questo video mostra esattamente di cosa stiamo parlando.
La funzione di ingrandimento dell'immagine aiuta i nostri utenti a ottenere l'aspetto e la sensazione del prodotto, oltre a garantire che sia la variante giusta del prodotto che desiderano acquistare.
Abbiamo utilizzato la libreria di react-image zoom
per creare questa funzionalità di ingrandimento dell'immagine.
Le librerie Image Magnify di solito hanno una lente (un quadrato che si muove quando il mouse si sposta all'interno dell'immagine). Poiché questa lente cambia la sua posizione superiore e sinistra con il movimento del mouse, viene rilevata come uno spostamento del layout che attiva CLS. Abbiamo controllato la pagina della libreria e altre librerie react simili ( react-image-magnify
, react-image-zoom
, react-image-magnifiers
) e abbiamo scoperto che tutte soffrono dello stesso problema di CLS.
Come l'abbiamo risolto
Abbiamo notato che react-image-zoom
utilizzava la libreria js-image-zoom
. Quindi abbiamo dovuto modificare la libreria di js-image zoom
per risolvere il problema.
La soluzione è piuttosto semplice. Mentre il mouse si sposta sull'immagine del prodotto, l'elemento della lente dell'immagine si sposta cambiando la sua posizione sinistra e in alto. Per risolvere il problema, abbiamo utilizzato transform translate
che sposta l'elemento su un nuovo livello, ovvero qualsiasi movimento che avviene su questo nuovo livello non causa più lo spostamento del layout:
Ho anche creato un PR per il repository originale in modo che altri sviluppatori che utilizzano questa libreria possano eliminare il problema CLS.
L'impatto del cambiamento
Dopo che il codice è stato distribuito in produzione, il CLS è stato corretto nella pagina dei dettagli del prodotto e il numero di pagine interessate da CLS è stato ridotto del 98%:
Poiché abbiamo usato transform
, ha anche aiutato a rendere l'immagine più fluida per gli utenti.
Nota : Paul Irish ha scritto un eccellente articolo su questo argomento.
Altre modifiche chiave che abbiamo apportato per CLS
Ci sono anche altri problemi che abbiamo affrontato attraverso molte pagine del nostro sito Web che contribuiscono a CLS. Esaminiamo questi elementi e componenti e vediamo come abbiamo cercato di mitigare i cambiamenti di layout che ne derivano.
Font Web:
Abbiamo notato che il caricamento tardivo dei caratteri causa frustrazione agli utenti poiché il contenuto lampeggia e provoca anche una certa quantità di cambiamenti di layout. Per ridurre al minimo questo abbiamo apportato alcune modifiche:- Abbiamo ospitato autonomamente i caratteri invece di caricarli da CDN di terze parti.
- Precarichiamo i caratteri.
- Usiamo il font-display opzionale.
Immagini:
Il valore di altezza o larghezza mancante nell'immagine fa sì che l'elemento dopo l'immagine si sposti una volta caricata l'immagine. Questo finisce per diventare un importante contributo a CLS. Poiché stiamo usando Next.js, abbiamo sfruttato il componente immagine integrato chiamatonext/images
. Questo componente incorpora diverse best practice relative alle immagini. È basato sul tag HTML<img>
e può aiutare a migliorare LCP e CLS. Consiglio vivamente di leggere questa RFC per scoprire le caratteristiche principali ei vantaggi del suo utilizzo.Scroll infinito:
Sul nostro sito Web, le pagine di elenco dei prodotti hanno uno scorrimento infinito. Quindi inizialmente, quando gli utenti scorrono fino alla fine della pagina, vedono un piè di pagina per una frazione di secondi prima che venga caricato il successivo set di dati, ciò provoca cambiamenti di layout. Per risolvere questo problema abbiamo fatto pochi passi:- Chiamiamo l'API per caricare i dati anche prima che l'utente raggiunga la fine assoluta dell'elenco.
- Abbiamo riservato spazio sufficiente per lo stato di caricamento e mostriamo gli scheletri del prodotto durante lo stato di caricamento. Quindi ora, quando l'utente scorre, non vede il piè di pagina per una frazione di secondo mentre i prodotti vengono caricati.
Addy Osmani ha scritto un articolo dettagliato su questo approccio che consiglio vivamente di controllare.
Da asporto chiave
- Sebbene Lighthouse e WebpageTest aiutino a scoprire i problemi di prestazioni che si verificano fino al caricamento della pagina, non possono rilevare i problemi di prestazioni dopo il caricamento della pagina.
- Le estensioni Web Vitals possono rilevare le modifiche CLS attivate dalle interazioni dell'utente, quindi se una pagina ha un valore CLS elevato ma Lighthouse o WebpageTest segnala CLS basso, l'estensione Web Vitals può aiutare a individuare il problema.
- I dati di Google Search Console si basano sui dati degli utenti reali in modo che possano anche indicare potenziali problemi di prestazioni che si verificano in qualsiasi momento del ciclo di vita di una pagina. Una volta rilevato e risolto un problema, controllare di nuovo la sezione del rapporto può aiutare a verificare l'efficacia della correzione delle prestazioni. Le modifiche si riflettono in pochi giorni nella sezione del rapporto sui dati vitali web.
Pensieri finali
Sebbene sia relativamente più difficile eseguire il debug dei problemi di CLS, l'utilizzo di una combinazione di strumenti diversi fino al caricamento della pagina (Lighthouse, WebPageTest) e l'estensione Web Vitals (dopo il caricamento della pagina) può aiutarci a individuare il problema. È anche una delle metriche che sta attraversando un grande sviluppo attivo per coprire un'ampia gamma di scenari e questo significa che il modo in cui viene misurato cambierà in futuro. Stiamo seguendo https://web.dev/evolving-cls/ per conoscere eventuali modifiche imminenti.
Quanto a noi, lavoriamo continuamente per migliorare anche altri Core Web Vital. Di recente, abbiamo implementato il precaricamento reattivo delle immagini e iniziato a fornire immagini in formato WebP che ci ha aiutato a ridurre il 75% del payload dell'immagine, ridurre l'LCP del 62% e l'indice di velocità del 24%. Puoi leggere maggiori dettagli sull'ottimizzazione per migliorare LCP e Speed Index o seguire il nostro blog di ingegneria per conoscere altri interessanti lavori che stiamo facendo.
Vorremmo ringraziare Alex Castle per averci aiutato a eseguire il debug del problema CLS sulla pagina del prodotto e a risolvere le stranezze nella next/images
.