Rezolvarea problemelor CLS într-un site web de comerț electronic alimentat de Next.js (studiu de caz)
Publicat: 2022-03-10Fairprice este unul dintre cele mai mari magazine alimentare online din Singapore. Căutăm în permanență zone de oportunități de îmbunătățire a experienței de cumpărături online a utilizatorului. Performanța este unul dintre aspectele esențiale pentru a ne asigura că utilizatorii noștri au o experiență de utilizator încântătoare, indiferent de dispozitivele lor sau de conexiunea la rețea.
Există mulți indicatori cheie de performanță (KPI) care măsoară diferite puncte în timpul ciclului de viață al paginii web (cum ar fi TTFB, domInteractive
și onload
), dar aceste valori nu reflectă modul în care utilizatorul final experimentează pagina.
Am vrut să folosim câțiva KPI-uri care corespund îndeaproape experienței reale a utilizatorilor finali, așa că știm că, dacă vreunul dintre acești KPI-uri nu funcționează bine, atunci va avea un impact direct asupra experienței utilizatorului final. Am descoperit că valorile de performanță centrate pe utilizator sunt potrivite pentru acest scop.
Există multe valori de performanță centrate pe utilizator pentru a măsura diferite puncte din ciclul de viață al unei pagini, cum ar fi FCP, LCP, FID, CLS și așa mai departe. Pentru acest studiu de caz, ne vom concentra în principal pe CLS.
CLS măsoară scorul total al tuturor schimbărilor neașteptate de aspect care au loc între momentul în care pagina începe să se încarce și până când este descărcată.
„
Prin urmare, având o valoare CLS scăzută pentru o pagină, se asigură că nu există schimbări aleatorii ale aspectului care să cauzeze frustrarea utilizatorului. Barry Pollard a scris un excelent articol aprofundat despre CLS.
Cum am descoperit problema CLS în pagina noastră de produse
Folosim Lighthouse și WebPagetest ca instrumente sintetice de testare a performanței pentru măsurarea CLS. De asemenea, folosim biblioteca web-vitals pentru a măsura CLS pentru utilizatori reali. În afară de aceasta, verificăm secțiunea Google Search Console Core Web Vitals Report pentru a ne face o idee despre eventualele probleme CLS în oricare dintre paginile noastre. În timp ce am explorat secțiunea de raport, am descoperit că multe adrese URL din pagina cu detaliile produsului aveau o valoare CLS mai mare de 0,1 sugerând că acolo are loc un eveniment major de schimbare a aspectului.
Depanarea problemei CLS folosind diferite instrumente
Acum că știm că există o problemă CLS pe pagina cu detaliile produsului, următorul pas a fost să identificăm ce element a cauzat-o. La început, am decis să rulăm câteva teste folosind instrumente de testare sintetice.
Așa că am condus farul pentru a verifica dacă a putut găsi vreun element care ar putea declanșa o schimbare majoră a aspectului, a raportat CLS la .004, care este destul de scăzut.
Pagina de raport Lighthouse are o secțiune de diagnosticare. De asemenea, nu a arătat niciun element care să provoace o valoare CLS ridicată.
Apoi am rulat WebpageTest și am decis să verificăm vizualizarea benzii de film:
Considerăm că această caracteristică este foarte utilă, deoarece putem afla ce element în care moment a determinat schimbarea aspectului. Dar când rulăm testul pentru a vedea dacă sunt evidențiate schimbări de aspect, nu a existat nimic care să contribuie la imensul LCS:
Particularitatea cu CLS este că înregistrează scorurile individuale ale schimbării aspectului pe toată durata de viață a paginii și le adaugă.
„
Notă : Modul în care este măsurat CLS a fost modificat din iunie 2021.
Deoarece Lighthouse și WebpageTest nu au putut detecta niciun element care a declanșat o schimbare majoră a aspectului, ceea ce înseamnă că se întâmpla după încărcarea inițială a paginii, posibil din cauza unei acțiuni a utilizatorului. Așa că am decis să folosim extensia Web Vitals Google Chrome, deoarece poate înregistra CLS pe o pagină în timp ce utilizatorul interacționează cu ea. După ce am efectuat diferite acțiuni, am constatat că scorul de schimbare a aspectului crește atunci când utilizatorul folosește funcția de mărire a imaginii.
Pentru a verifica încrucișat dacă se produce schimbarea aspectului în timp ce trece mouse-ul pe imagine, am folosit fragmentul de cod de mai jos de la https://web.dev/cls/ care adaugă console.log
când are loc schimbarea aspectului:
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});
În urma investigațiilor ulterioare, am constatat că ASDA s-a confruntat cu o problemă similară și a ridicat-o pentru Chrome.
Cauza de bază
Pe pagina cu detaliile produsului, utilizatorii pot muta mouse-ul peste imaginea produsului pentru a vedea o secțiune mărită a imaginii, alături de imaginea reală a produsului, deoarece acest videoclip arată exact despre ce vorbim.
Funcția de mărire a imaginii ajută utilizatorii noștri să obțină aspectul și senzația produsului, precum și să se asigure că este varianta potrivită a produsului pe care doresc să-l cumpere.
Am folosit biblioteca de react-image zoom
pentru a construi această funcționalitate de mărire a imaginii.
Bibliotecile Image Magnify au de obicei o lentilă (un pătrat care se mișcă atunci când mouse-ul se mișcă în interiorul imaginii). Deoarece acest obiectiv își schimbă poziția sus și stânga cu mișcarea mouse-ului, este detectat ca o schimbare de aspect care declanșează CLS. Am verificat pagina bibliotecii, precum și alte biblioteci similare react ( react-image-magnify
, react-image-zoom
, react-image-magnifiers
) și am constatat că toate suferă de aceeași problemă CLS.
Cum am rezolvat-o
Am observat că react-image-zoom
folosea biblioteca js-image-zoom
. Așa că a trebuit să modificăm biblioteca de js-image zoom
pentru a remedia problema.
Soluția este destul de simplă. În timp ce mouse-ul se deplasează pe imaginea produsului, elementul lentilei de imagine se mișcă prin schimbarea poziției din stânga și de sus. Pentru a remedia problema, am folosit transform translate
care mută elementul într-un nou strat, adică orice mișcare care are loc pe acest nou strat nu mai provoacă schimbarea aspectului:
De asemenea, am creat un PR pentru repo-ul original, astfel încât alți dezvoltatori care folosesc această bibliotecă să poată scăpa de problema CLS.
Impactul Schimbării
După ce codul a fost implementat în producție, CLS a fost remediat pe pagina cu detaliile produsului și numărul de pagini afectate de CLS a fost redus cu 98%:
Deoarece am folosit transform
, a ajutat, de asemenea, ca imaginea să mărească o experiență mai fluidă pentru utilizatori.
Notă : Paul Irish a scris un articol excelent pe acest subiect.
Alte modificări cheie pe care le-am făcut pentru CLS
Există, de asemenea, alte probleme cu care ne-am confruntat prin multe pagini de pe site-ul nostru, care contribuie la CLS. Să trecem prin acele elemente și componente și să vedem cum am încercat să atenuăm schimbările de aspect care decurg din acestea.
Fonturi web:
Am observat că încărcarea cu întârziere a fonturilor provoacă frustrări utilizatorilor, deoarece conținutul clipește și provoacă, de asemenea, unele schimbări de aspect. Pentru a minimiza acest lucru, am făcut câteva modificări:- Am autogăzduit fonturile în loc să le încărcăm de pe CDN-ul terță parte.
- Preîncărcăm fonturile.
- Folosim opțional font-display.
Imagini:
Lipsa valorii înălțimii sau lățimii din imagine face ca elementul de după imagine să se deplaseze odată ce imaginea este încărcată. Aceasta ajunge să devină un contributor major la CLS. Deoarece folosim Next.js, am profitat de componenta de imagine încorporată numitănext/images
. Această componentă încorporează mai multe bune practici legate de imagine. Este construit pe eticheta HTML<img>
și poate ajuta la îmbunătățirea LCP și CLS. Recomand cu căldură să citiți acest RFC pentru a afla caracteristicile cheie și avantajele utilizării acestuia.Derulare infinită:
Pe site-ul nostru, paginile cu lista de produse au defilare infinită. Așadar, inițial, atunci când utilizatorii derulează în partea de jos a paginii, văd un subsol pentru o fracțiune de secunde înainte de încărcarea următorului set de date, acest lucru provoacă schimbări de aspect. Pentru a rezolva acest lucru am făcut câțiva pași:- Apelăm API-ul pentru a încărca date chiar înainte ca utilizatorul să ajungă la capătul absolut al listei.
- Am rezervat suficient spațiu pentru starea de încărcare și afișăm scheletele produselor în timpul stării de încărcare. Deci, acum, când utilizatorul derulează, nu vede subsolul pentru o fracțiune de secunde în timp ce produsele se încarcă.
Addy Osmani a scris un articol detaliat despre această abordare pe care vă recomand cu căldură să îl verificați.
Recomandări cheie
- Deși Lighthouse și WebpageTest ajută la descoperirea problemelor de performanță care apar până la încărcarea paginii, acestea nu pot detecta problemele de performanță după încărcarea paginii.
- Extensiile Web Vitals pot detecta modificări CLS declanșate de interacțiunile utilizatorului, așa că dacă o pagină are o valoare CLS mare, dar Lighthouse sau WebpageTest raportează CLS scăzut, atunci extensia Web Vitals poate ajuta la identificarea problemei.
- Datele Google Search Console se bazează pe datele utilizatorilor reali, astfel încât, de asemenea, pot indica potențiale probleme de performanță care apar în orice moment al ciclului de viață al unei pagini. Odată ce o problemă este detectată și remediată, verificarea din nou a secțiunii de raport poate ajuta la verificarea eficacității remedierii performanței. Modificările sunt reflectate în câteva zile în secțiunea de raportare web vitals.
Gânduri finale
Deși problemele CLS sunt relativ mai greu de depanat, utilizarea unei combinații de instrumente diferite până la încărcarea paginii (Lighthouse, WebPageTest) și extensia Web Vitals (după încărcarea paginii) ne poate ajuta să identificăm problema. Este, de asemenea, una dintre metricile care trece printr-o mulțime de dezvoltare activă pentru a acoperi o gamă largă de scenarii și asta înseamnă că modul în care este măsurat va fi schimbat în viitor. Urmărim https://web.dev/evolving-cls/ pentru a afla despre orice modificări viitoare.
În ceea ce ne privește, lucrăm în mod continuu pentru a îmbunătăți și alte elemente vitale ale Core Web. Recent, am implementat preîncărcarea imaginilor receptive și am început să difuzăm imagini în format WebP, ceea ce ne-a ajutat să reducem 75% din încărcarea utilă a imaginii, să reducem LCP cu 62% și Speed Index cu 24%. Puteți citi mai multe detalii despre optimizarea pentru îmbunătățirea LCP și Speed Index sau puteți urmări blogul nostru de inginerie pentru a afla despre alte activități interesante pe care le facem.
Dorim să-i mulțumim lui Alex Castle pentru că ne-a ajutat să depanăm problema CLS de pe pagina produsului și să rezolvăm necazurile în implementarea next/images
.