Îmbunătățirea performanței unui magazin online (studiu de caz)

Publicat: 2022-03-10
Rezumat rapid ↬ Obținerea unui scor bun de performanță de la Google este greu pentru orice site web, dar a face acest lucru pentru un magazin online este și mai greu. Am obținut scoruri verzi – chiar și câteva pentru mobil. Iată cum am făcut-o.

Fiecare dezvoltator front-end urmărește același sfânt Graal al performanței: scoruri verzi în Google Page Speed. Semnele tangibile ale muncii bine făcute sunt întotdeauna apreciate. La fel ca vânătoarea de Graal, totuși, trebuie să vă întrebați dacă acesta este într-adevăr răspunsul pe care îl căutați. Performanța reală pentru utilizatorii dvs. și modul în care „se simte” site-ul web atunci când îl utilizați nu ar trebui să fie reduse, chiar dacă vă costă un punct sau două în Viteza paginii (altfel, toți am avea doar o bară de căutare și fără stil). text).

Lucrez la o mică agenție digitală, iar echipa mea lucrează în mare parte pe site-uri web și magazine corporative mari - viteza paginii intră în discuție la un moment dat, dar de obicei, până atunci, răspunsul este că ar fi nevoie de o rescrie uriașă pentru a realiza cu adevărat orice. un efect secundar nefericit al dimensiunii și structurii proiectelor în corporații.

Lucrul cu jewellerybox în magazinul său online a fost o schimbare de ritm binevenită pentru noi. Proiectul a constat în actualizarea software-ului magazinului la propriul nostru sistem open-source și refacerea front-end-ului magazinului de la zero. Designul a fost realizat de o agenție de design și UX care s-a ocupat și de prototipul HTML (bazat pe Bootstrap 4). De acolo, l-am încorporat în șabloane - și pentru o dată, am avut un client obsedat și de performanța site-ului web.

Pentru lansare, ne-am concentrat în mare parte pe scoaterea noului design, dar odată ce relansarea site-ului a fost lansată, am început să ne concentrăm atenția asupra transformării scorurilor roșii și portocalii în verzi. A fost o călătorie de mai multe luni plină de decizii dificile, cu multe discuții despre ce optimizări merită urmărite. Astăzi, site-ul web este mult mai rapid și se clasează foarte bine în diverse vitrine și benchmark-uri. În acest articol, voi evidenția o parte din munca pe care am făcut-o și cum am reușit să ne atingem viteza.

Acest raport pentru mobil Lighthouse pentru prima pagină a arătat că trebuie făcută multă muncă.
Acest raport pentru mobil Lighthouse pentru prima pagină a arătat că trebuie făcută multă muncă. (Previzualizare mare)

Magazinele online sunt puțin diferite

Înainte de a intra în detalii, să luăm un scurt moment pentru a vorbi despre modul în care magazinele online sunt diferite de multe alte site-uri web (dacă știți deja acest lucru, ne vom întâlni cu tine în secțiunea următoare). Când vorbim despre un site de comerț electronic, principalele pagini pe care le veți avea sunt:

  • pagina de start (și paginile de „conținut”)
  • categorii și pagini de căutare,
  • pagini cu detalii despre produs,
  • coșul și casă (evident).

Pentru acest articol, ne vom concentra pe primele trei și pe ajustările de performanță pentru acestea. Casa de casă este propria sa bestie. Acolo veți avea o mulțime de JavaScript suplimentar și de logică back-end pentru a calcula prețurile, plus câteva apeluri de service pentru a obține furnizorul de transport adecvat și estimări de preț în funcție de țara în care este expediat.

Acest lucru este evident în plus față de validarea câmpurilor formularelor de care veți avea nevoie pentru a înregistra adresele de facturare și expediere. Adăugați la asta și furnizorul de plăți și veți avea câteva pagini pe care nimeni nu va dori să le atingă după ce au fost testate corespunzător și funcționează.

Prima pagină este editabilă prin CMS și conține o mulțime de imagini și carusele.
Prima pagină este editabilă prin CMS și conține o mulțime de imagini și carusele. (Previzualizare mare)
O versiune a paginii cu detaliile produsului cu totul: alegeți o dimensiune, adăugați-i gravuri, poate schimbați culoarea.
O versiune a paginii cu detaliile produsului cu totul: alegeți o dimensiune, adăugați-i gravuri, poate schimbați culoarea. (Previzualizare mare)

Care este primul lucru la care te gândești când îți imaginezi un magazin online? Imagini — o mulțime și o mulțime de imagini ale produselor. Ele sunt practic peste tot și vă vor domina designul. În plus, vei dori să arăți multe produse pentru a-i determina pe oameni să cumpere de la tine - deci este un carusel. Dar asteapta! Oamenii dau clic pe produsele din el? Putem afla punând niște urmăriri pe carusel. Dacă îl urmărim, îl putem optimiza! Și dintr-o dată, avem pe paginile noastre carusele de produse externe, alimentate de AI.

Chestia este că un carusel nu va fi ultimul element de penalizare pe care îl adăugați pe pagină pentru a prezenta mai multe produse în speranța de a atrage mai multe vânzări. Desigur, un magazin are nevoie de elemente interactive , fie că este vorba de mărirea imaginii produsului, niște videoclipuri, o numărătoare inversă până la termenul limită de livrare de astăzi sau o fereastră de chat pentru a intra în contact cu asistența pentru clienți.

Toate acestea sunt foarte importante atunci când măsurați conversiile direct ca venit . În plus, la fiecare câteva luni, cineva din echipă va descoperi câteva funcționalități noi interesante care ar putea fi adăugate, astfel încât complexitatea și JavaScript încep să se acumuleze, chiar dacă ai început cu cea mai bună intenție de a-l menține slab.

Și deși de obicei puteți stoca în cache întreaga pagină a unui articol, nu același lucru este valabil pentru multe pagini și elemente de magazin. Unele sunt specifice utilizatorului, cum ar fi coșul de cumpărături din antet sau lista de dorințe și, din cauza naturii personale a datelor, nu ar trebui să fie niciodată stocate în cache. În plus, dacă ai bunuri fizice, ai de-a face cu inventarul viu: în special în timpul goanei de Crăciun, vei avea nevoie de informațiile despre inventar pentru a fi precise și la zi; deci, veți avea nevoie de o strategie de stocare în cache mai complexă, care vă permite să stocați în cache părți ale paginii și să combinați totul împreună în timpul redării pe server.

Dar chiar și în fazele de planificare, capcanele așteaptă. Într-o fază de proiectare – și adesea și în faza de prototip – veți lucra cu nume și descrieri ale produselor fin lucrate, toate aproape uniforme ca lungime și imagini de produs ideale. Arată uimitor! Singura problema? În realitate, informațiile despre produs pot fi foarte diferite în lungime, ceea ce vă poate strica designul. Cu câteva mii de produse, nu le puteți verifica pe fiecare.

Prin urmare, este de ajutor dacă designerii sau oamenii care testează prototipul cu șiruri foarte scurte și foarte lungi pentru a se asigura că designul încă se potrivește. În mod similar, faptul că informațiile apar de două ori în HTML, o dată pentru desktop și o dată pentru mobil, poate fi o problemă uriașă pentru un magazin - mai ales dacă este vorba de informații complexe, cum ar fi detalii despre produs, coșul de cumpărături sau fațete pentru filtrele unei categorii de produse. pagină. Menținerea acestora în sincronizare este greu de făcut - așa că, vă rugăm să ajutați un coleg dezvoltator și nu o faceți.

Un alt lucru care nu ar trebui să fie niciodată o idee ulterioară și care ar trebui încorporat încă de la etapa de prototip este accesibilitatea. Mai multe instrumente de acolo vă pot ajuta cu unele dintre elementele de bază, de la a avea text alternativ pentru toate imaginile și pictogramele cu o funcție, la contrastul de culoare, până la a ști ce atribute ARIA să utilizați unde (și când nu). Încorporarea acestui lucru de la început este mult mai ușoară decât mai târziu și permite tuturor să se bucure de site-ul web la care lucrați.

Iată un sfat: dacă nu ați văzut oameni folosind un cititor de ecran sau navigând doar cu o tastatură, videoclipurile despre acesta pot fi găsite cu ușurință pe YouTube. Vă va schimba înțelegerea acestor subiecte.

Înapoi la performanță: de ce este atât de important să îmbunătățim din nou performanța unui magazin? Răspunsul evident este că vrei ca oamenii să cumpere de la tine . Există mai multe moduri în care puteți afecta acest lucru, iar viteza site-ului dvs. este una mare. Studiile arată că fiecare secundă suplimentară de timp de încărcare are un impact semnificativ asupra ratei de conversie. În plus, viteza paginii este un factor de clasare pentru căutare și, de asemenea, pentru Google Ads. Deci, îmbunătățirea performanței va avea un efect tangibil asupra rezultatului final.

Mai multe după săritură! Continuați să citiți mai jos ↓

Lucruri practice pe care le-am făcut

Unele blocaje de performanță sunt ușor de identificat, dar o îmbunătățire profundă este o călătorie mai lungă, cu multe întorsături. Am început cu toate lucrurile obișnuite, cum ar fi reverificarea stocării în cache a resurselor, să vedem ce am putea prelua sau încărca în mod asincron, asigurându-ne că folosim HTTP/2 și TLSv1.3. Multe dintre ele sunt acoperite în prezentarea generală utilă a CSS-Tricks, iar Smashing Magazine oferă o listă de verificare PDF excelentă.

Primele lucruri în primul rând: lucrurile încărcate pe toate paginile

Să vorbim despre resurse, și nu doar despre CSS sau JavaScript (pe care le vom trata mai târziu). Am început prin a ne uita la lucrurile partajate pe mai multe ecrane, fiecare dintre acestea putând avea un impact. Abia după aceea ne-am concentrat asupra tipurilor de pagini și problemelor unice pentru acestea. Unele elemente comune au fost următoarele.

Se încarcă pictograma

Ca și pe atâtea site-uri web, folosim mai multe pictograme în designul nostru. Prototipul a venit cu câteva pictograme personalizate care erau simboluri SVG încorporate. Acestea au fost stocate ca o etichetă svg mare în capul HTML al paginii, cu un simbol pentru fiecare dintre pictograme care a fost apoi folosit ca un svg legat în corpul HTML. Acest lucru are efectul frumos de a le face direct disponibile pentru browser atunci când documentul se încarcă, dar, evident, browserul nu le poate stoca în cache pentru întregul site.

Așa că am decis să le mutăm într-un fișier SVG extern și să-l preîncărcăm. În plus, am inclus doar pictogramele pe care le folosim de fapt. În acest fel, fișierul poate fi stocat în cache pe server și în browser și nu vor trebui interpretate SVG-uri superflue. De asemenea, susținem utilizarea Font Awesome pe pagină (pe care îl încărcăm prin JavaScript), dar îl încărcăm la cerere (adăugând un script mic care verifică orice etichete <i> și apoi încărcând JavaScript Font Awesome pentru a obține orice SVG icoane pe care le găsește). Deoarece rămânem la propriile pictograme de deasupra pliului, putem rula întregul script după ce DOM s-a încărcat.

De asemenea, folosim emoji în unele locuri pentru pictograme colorate, ceva la care niciunul dintre noi nu s-a gândit cu adevărat, dar la care editorul nostru de conținut, Daena, a cerut și care sunt o modalitate excelentă de a afișa pictograme fără niciun efect negativ asupra performanței (singura avertizare fiind diferitele modele pe diferite sisteme de operare).

Încărcarea fontului

La fel ca pe atâtea alte site-uri web, folosim fonturi web pentru nevoile noastre de tipografie. Designul necesită două fonturi în corp ( Josefin Sans în două greutăți), unul pentru titluri ( Nixie One ) și unul pentru text cu stil special ( Moonstone Regular ). De la început, le-am stocat local, cu o rețea de livrare a conținutului (CDN) pentru performanță, dar după ce am citit minunatul articol al lui Simon Hearne despre evitarea schimbărilor de layout cu încărcarea fontului, am experimentat cu eliminarea versiunii bold și folosirea celei obișnuite.

În testele noastre, diferența vizuală a fost atât de mică încât niciunul dintre testerii noștri nu a putut să spună fără să le vadă pe ambele în același timp. Deci, am renunțat la greutatea fontului . În timp ce lucram la acest articol și pregătim un ajutor vizual pentru această secțiune, am dat peste diferențe mai mari între browserele bazate pe Chromium pe Mac și cele bazate pe WebKit pe ecranele de înaltă rezoluție (da, complexitate!). Acest lucru a dus la o nouă rundă de discuții despre ce ar trebui să facem.

După câteva du-te și înapoi, am optat să păstrăm falsul bold și să folosim -webkit-text-stroke: 0.3px pentru a ajuta acele browsere. Diferența față de utilizarea greutății reale a fontului separat este ușoară, dar nu suficientă pentru cazul nostru de utilizare, în care nu folosim aproape niciun font aldine, ci doar câteva cuvinte la un moment dat (ne pare rău, pasionați de fonturi).

Vedeți Pen [Studiu de caz Jewellerybox (Exemplu #1)](https://codepen.io/smashingmag/pen/MWprwyE) de Pfenya.

Vedeți Studiul de caz Pen Jewellerybox (Exemplul #1) de Pfenya.

În plus, mai multe produse pot fi personalizate cu gravuri . Aceste gravuri se pot face în mai multe fonturi, iar pentru unii oferim o previzualizare cu fontul aplicat. Pentru acestea, descarcăm fontul la cerere atunci când este ales în selectorul de fonturi drop-down. Previzualizările din meniul derulant sunt exemple de imagini ale felului în care arată fontul. Acest lucru ne împiedică să fie nevoiți să descărcați 10 sau mai multe fișiere cu fonturi suplimentare.

Suport moștenire

Într-o zi, CSS-Tricks m-a surprins cu un articol despre „How to Favicon in 2021”. Folosim fiecare dimensiune de pictogramă atingere din lume — articolul m-a făcut să reevaluez ceea ce avem de fapt nevoie și mi-a arătat că uneori ceea ce era adevărat cu câțiva ani în urmă ar putea să nu mai fie nevoie. Pe baza articolului, ne-am limitat listele de pictograme favicon și atingere la versiunile recomandate.

În mod similar, am convertit și un font pe care îl aveam doar ca versiune WOFF în WOFF2 , care este mult mai mic și am decis să oferim WOFF2 pentru fonturi (cu WOFF rămânând ca alternativă). Și am curățat directivele CSS care nu mai sunt necesare.

Încărcare leneșă și la cerere

Mai multe valori se concentrează pe timpul după care utilizatorii pot interacționa cu pagina. Logica dictează că a avea mai puține elemente de încărcat înseamnă că acest punct va fi atins mai devreme. Pentru a ține seama de acest lucru, este important să vă întrebați care părți ale paginii sunt esențiale și de care utilizatorul va avea nevoie doar mai târziu. Am trecut prin multe dezbateri și încercări și erori în acest sens.

Cascada activității în rețea a ajutat foarte mult aici, dar la fel și gândirea la fluxurile de utilizatori. De exemplu, imaginea mărită a produsului poate fi încărcată prima dată când un utilizator interacționează cu imaginea produsului, iar imaginile din subsol nu apar de obicei deasupra pliului și pot fi încărcate ulterior. Dacă sunteți îngrijorat de încetiniri, puteți încă să lucrați cu resurse de preluare anticipată.

Un lucru pe care l-am observat foarte devreme a fost impactul mare al clientului de chat. Numai JavaScript avea peste 500 KB și, deși, din păcate, nu mai am o diagramă, încărcarea a fost lent. Chiar dacă JavaScript a fost setat să se încarce asincron, Google îl includea în măsurătorile de timp până la interactiv.

Nu am reușit să urmărim pe deplin de ce a fost cazul, dar între el și dimensiunea lor, am început să căutăm alternative, în loc să încercăm să reparăm ceva asupra căruia aveam un control limitat. Am convins jewellerybox să încerce un widget de chat open-source găzduit în schimb , care ne oferă mai mult control asupra modului în care se încarcă și care este, de asemenea, mult mai mic. Pentru a o îmbunătăți și mai mult, încărcăm inițial doar pictograma pentru chat; restul se încarcă când faceți clic pentru a-l deschide.

Caruselul invizibil al unei terțe părți

Jewellerybox a vrut să încerce un serviciu terță parte care folosește AI pentru a îmbunătăți personalizarea produselor în caruselele de pe mai multe pagini. Am decis să apelăm API-ul său din back-end pentru aceasta, astfel încât să avem mai mult control asupra a ceea ce se încarcă (fără dependențe mari de JavaScript) și cât timp așteptăm un răspuns de la serviciul lor (cu unele alternative definite). Din acest motiv, caruselurile se încarcă în același mod ca și cele nepersonalizate și pot fi stocate în cache și cu o cheie cache unică.

Acesta este un carusel terță parte, dar arată și se încarcă ca cel implicit.
Acesta este un carusel terță parte, dar arată și se încarcă ca cel implicit. (Previzualizare mare)

Totuși, există un dezavantaj: aceasta înseamnă că redarea inițială a paginii pe partea serverului ar putea fi mai lentă dacă nu este stocată în cache. Din acest motiv, lucrăm în prezent la modalități alternative de a injecta rezultatele după ce pagina s-a încărcat și a redat mai întâi un substituent.

În al doilea rând: Optimizarea JavaScript - O luptă dificilă împotriva dușmanilor externi

Caruselul ne duce la a doua mare zonă pe care ne-am concentrat: JavaScript. Am auditat JavaScript-ul pe care îl aveam, iar majoritatea provine din biblioteci pentru diferite sarcini, cu foarte puțin cod personalizat. Am optimizat codul pe care l-am scris noi înșine, dar, evident, puteți face doar atât de multe dacă este doar o fracțiune din codul dvs. total - marile câștiguri se află în biblioteci.

Optimizarea lucrurilor din biblioteci sau scoaterea părților de care nu aveți nevoie este, după toate probabilitățile, o misiune prostească. Nu știți cu adevărat de ce există unele părți și nu veți putea niciodată să actualizați biblioteca din nou fără multă muncă manuală. Având în vedere acest lucru, am făcut un pas înapoi și am analizat ce biblioteci folosim și pentru ce avem nevoie de ele și am investigat pentru fiecare dintre ele dacă există o alternativă mai mică sau mai rapidă care se potrivește la fel de bine nevoilor noastre.

În mai multe cazuri, a existat! De exemplu, am decis să înlocuim biblioteca de glisare Slick cu GliderJS, care are mai puține funcții, dar toate de care avem nevoie, plus că este mai rapid de încărcat și are suport CSS mai modern! În plus, am luat o mulțime de biblioteci autonome din fișierul principal JavaScript și am început să le încărcăm la cerere.

Deoarece folosim Bootstrap 4, încă includem jQuery pentru proiect, dar lucrăm la înlocuirea totul cu implementări native. Pentru Bootstrap în sine, există o versiune bootstrap.native pe GitHub fără dependența de jQuery pe care o folosim acum. Are dimensiuni mai mici și rulează mai repede. În plus, generăm două versiuni ale fișierului nostru principal JavaScript: una fără polyfills și una cu ele incluse și schimbăm versiunea cu ele atunci când browserul are nevoie de ele, permițându-ne să oferim o versiune principală simplificată pentru majoritatea oamenilor. Am testat un serviciu „polyfill-on-demand”, dar performanța nu a îndeplinit așteptările noastre.

Un ultim lucru pe tema jQuery. Inițial, l-am încărcat de pe serverul nostru. Am văzut îmbunătățiri ale performanței sistemului nostru de testare atunci când l-am încărcat prin Google CDN, dar Page Speed ​​Insights s-a plâns de performanță (mă întreb cine ar putea rezolva asta), așa că am testat noi înșine să-l găzduim din nou, iar în producție a fost de fapt mai rapid datorită CDN-ul pe care îl folosim.

Lecție învățată : Un mediu de testare nu este un mediu de producție, iar remediile pentru unul ar putea să nu fie valabile pentru celălalt.

În al treilea rând: Imagini - formate, dimensiuni și tot acel jazz

Imaginile sunt o mare parte din ceea ce face un magazin online. O pagină va avea de obicei câteva zeci de imagini, chiar înainte de a număra diferitele versiuni pentru diferite dispozitive. Site-ul web Jewellerybox există de aproape 10 ani și multe produse au fost disponibile în cea mai mare parte a timpului, așa că imaginile originale ale produselor nu sunt uniforme ca dimensiune și stil, iar numărul de fotografii de produs poate varia, de asemenea.

În mod ideal, am dori să oferim imagini receptive pentru diferite dimensiuni de vizualizare și densități de afișare în formate moderne, dar orice modificare a cerințelor ar însemna multă muncă de conversie de făcut. Din acest motiv, utilizăm în prezent o dimensiune optimizată a imaginilor produselor, dar nu avem imagini receptive pentru acestea. Actualizarea care este pe harta de parcurs, dar nu este banală. Paginile de conținut oferă mai multă flexibilitate, iar acolo generăm și folosim diferite dimensiuni și includem atât formate WebP, cât și formate alternative.

Având atât de multe imagini, adaugă multă greutate sarcinii utile inițiale. Deci, când și cum să încărcați imaginile a devenit un subiect uriaș. Încărcarea leneșă sună ca soluția, dar dacă este aplicată universal, poate încetini imaginile vizibile inițial, mai degrabă decât să le încarce direct (sau cel puțin se simte așa pentru utilizator). Din acest motiv, am optat pentru o combinație de încărcare directă a primelor câteva și încărcare leneră a restului, folosind o combinație de încărcare leneră nativă și un script.

Pentru logo-ul site-ului, folosim un fișier SVG, pentru care am primit o versiune inițială de la client. Logo-ul este un font complicat din care lipsesc părți din litere, deoarece acestea ar fi într-o imprimare imperfectă realizată manual. La dimensiuni mari, ar trebui să afișați detaliile, dar pe site-ul web nu îl folosim niciodată peste 150 pe 30 de pixeli. Fișierul original avea o dimensiune de 192 KB, nu mare, dar nici super-mic. Am decis să ne jucăm cu SVG-ul și să reducem detaliile din el și am ajuns să avem o versiune de 40 KB dezarhivată. Nu există nicio diferență vizuală la dimensiunile afișajului pe care le folosim.

Puteți observa o diferență semnificativă, chiar și la această dimensiune mai mare?
Puteți observa o diferență semnificativă, chiar și la această dimensiune mai mare? (Previzualizare mare)

Ultimul, dar cu siguranță nu în ultimul rând: CSS

CSS critic

CSS figurează foarte mult în Raportul despre experiența utilizatorului Chrome (CrUX) de la Google și, de asemenea, apare foarte mult în raportul și recomandările Google Page Speed ​​Insights. Unul dintre primele lucruri pe care le-am făcut a fost să definim niște CSS critice, pe care le încărcăm direct în HTML, astfel încât să fie disponibil pentru browser cât mai curând posibil - aceasta este arma dumneavoastră principală pentru a lupta împotriva schimbărilor de aspect al conținutului (CLS). Am optat pentru o combinație de extragere automată a CSS-ului critic bazat pe o pagină prototip și un mecanism cu ajutorul căruia putem defini numele claselor care urmează să fie extrase (inclusiv toate subregulile). Facem acest lucru separat pentru stilurile generale, stilurile de pagină de produs și stilurile de categorii care sunt adăugate pe tipurile de pagină respective.

Ceea ce am învățat din asta și care a cauzat unele erori între ele este că trebuie să fim atenți ca ordinea CSS să nu fie schimbată de acest lucru. Între diferite persoane care scriu codul, cineva care adaugă o modificare mai târziu în fișier și un instrument automat care extrage lucruri, poate deveni dezordonat.

Dimensiuni explicite împotriva CLS

Pentru mine, CLS este ceva ce Google a scos din pălărie, iar acum trebuie să ne ocupăm cu toții de el și să ne învăluim capul colectiv în jurul lui. În timp ce înainte, puteam pur și simplu să lăsăm containerele să-și obțină dimensiunea de la elementele din ele, acum încărcarea acelor elemente se poate încurca cu dimensiunea cutiei. Având în vedere asta, am folosit fila „Performanță” din Instrumentele pentru dezvoltatori și generatorul GIF Layout Shift foarte util pentru a vedea ce elemente cauzează CLS. De acolo, ne-am uitat nu numai la elementele în sine, ci și la părinții lor și am analizat proprietățile CSS care ar avea un impact asupra aspectului. Uneori am avut noroc – de exemplu, logo-ul avea nevoie doar de o dimensiune explicită setată pe mobil pentru a preveni o schimbare a aspectului – dar alteori, lupta a fost reală.

Sfat pro: Uneori, o schimbare este cauzată nu de elementul aparent, ci de elementul care îl precede. Pentru a identifica posibilii vinovați, concentrați-vă pe proprietățile care se modifică în dimensiune și spațiere. Întrebarea de bază pe care trebuie să ți-o pui este: Ce ar putea face ca acest bloc să se miște?

Exemplu de schimbare CLS pe ​​care am văzut-o &mdash; toate casetele din conținut au fost cauzate de unghiul de colecție Nouă.
Exemplu de schimbare CLS pe ​​care l-am văzut - toate casetele din conținut au fost cauzate de unghiul de colecție Nouă. (Previzualizare mare)

Deoarece sunt atât de multe imagini pe pagină, a le face să se comporte corect cu CLS, de asemenea, ne-a cauzat ceva de lucru. Barry Pollard ne amintește pe bună dreptate despre asta în articolul său, „Setarea înălțimii și lățimii imaginilor este din nou importantă”. Am petrecut mult timp pentru a descoperi valorile corecte de lățime și înălțime (plus raporturile de aspect) pentru imaginile noastre în fiecare caz pentru a le adăuga din nou la HTML. Ca urmare, nu mai există nicio schimbare de aspect pentru imagini, deoarece browserul primește informațiile devreme.

Cazul Scorului Misterios CLS

După ce am eliminat o mulțime de probleme mari CLS din partea de sus a paginii, am lovit un blocaj. Uneori (nu întotdeauna) când ne uităm la Page Speed ​​sau Lighthouse, am obținut un scor CLS de peste 0,3, dar niciodată în fila „Performanță”. Generatorul GIF Layout Shift îl arăta uneori, dar părea că întregul container al paginii se mișcă .

Cu limitarea rețelei și a procesorului activată, am văzut-o în sfârșit în capturi de ecran! Antetul de pe mobil creștea cu 2 pixeli în înălțime din cauza elementelor din interiorul acestuia. Deoarece antetul este oricum o înălțime fixă ​​pe mobil, am urmat soluția simplă și i-am adăugat o înălțime explicită - caz închis. Dar ne-a costat o mulțime de nervi și arată că instrumentele de aici sunt încă foarte imprecise.

Schimbarea aspectului de Doom &mdash; asta a durat mult timp să-ți dai seama.
Layout Shift of Doom - a durat mult timp pentru a înțelege. (Previzualizare mare)

Acest lucru nu funcționează - Să o refacem!

După cum știm cu toții, scorurile mobile sunt mult mai dure pentru Page Speed ​​decât pentru desktop și un domeniu în care au fost deosebit de proaste pentru noi a fost pe paginile de produse. Scorul CLS a fost peste acoperiș, iar pagina a avut și probleme de performanță (mai multe carusele, file și elemente care nu pot fi stocate în cache vor face asta). Pentru a înrăutăți lucrurile, aspectul paginii însemna că unele informații erau amestecate sau adăugate de două ori.

Pe desktop, avem practic două coloane pentru conținut:

  • Coloana A : caruselul cu fotografii ale produsului, uneori urmat de citate blogger, urmate de un aspect cu file cu informații despre produs.
  • Coloana B : Numele produsului, prețul, descrierea și butonul „adaugă în coș”.
  • Rândul C : caruselul de produse cu produse similare.

Pe mobil, însă, caruselul cu fotografii ale produsului trebuia să vină mai întâi, apoi coloana B, apoi aspectul cu file din coloana A. Din această cauză, anumite informații au fost duplicate în HTML, fiind controlate de display: none , iar comanda era în curs comutat cu proprietatea flex: order . Cu siguranță funcționează, dar nu este bun pentru scorurile CLS, deoarece practic totul trebuie reordonat.

Zonele paginii sunt vizualizate pe desktop și pe mobil pentru a arăta problema principală.
Zonele paginii sunt vizualizate pe desktop și pe mobil pentru a arăta problema principală. (Previzualizare mare)

M-am hotărât asupra unui experiment simplu în CodePen: aș putea realiza același aspect de bază al casetelor pe desktop și pe mobil regândind HTML-ul și folosind display: grid în loc de flexbox, iar asta mi-ar permite să rearanjez pur și simplu zonele grilei după cum este necesar? Pe scurt, a funcționat și a rezolvat CLS și are avantajul suplimentar că numele produsului apare acum mult mai devreme în HTML decât înainte - un câștig suplimentar SEO!

Vedeți Pen [Studiu de caz Jewellerybox (Exemplu #2)](https://codepen.io/smashingmag/pen/OJpzyLg) de Pfenya.

Vedeți Studiul de caz Pen Jewellerybox (Exemplul #2) de Pfenya.

Hacking un carusel pentru CLS

Cuvântul „carusel” a apărut deja de mai multe ori – și cu un motiv întemeiat. Nu numai că am schimbat biblioteca carusel pe care o folosim (și am schimbat comportamentul de încărcare a imaginilor din ea), a trebuit să ne ocupăm și de aceasta pentru CLS deoarece avem mai multe pagini pe care caruselul se află deasupra pliului și, prin urmare, ar putea avea un impact mare asupra scorurilor de viteză.

Am început prin a încărca caruselul mai târziu pentru a reduce timpul de interacțiune , dar asta a cauzat o întârziere vizibilă până când JavaScript s-a declanșat și diapozitivele s-au mutat de la a fi unul sub celălalt la a fi pe un rând. Am încercat o mulțime de moduri de a scrie CSS pentru a preveni acest lucru și pentru a păstra totul pe un singur rând, inclusiv ascunderea întregului carusel până când a terminat de încărcat. Nimic nu ne-a oferit genul de soluție pe care ne-am fi dorit să o vedem când vizităm un magazin ca utilizator.

Îmi pare rău pentru această scurtă dezvăluire, dar într-adevăr, caruselele de produse și categorii sunt furtuna perfectă de elemente flexibile într-un magazin receptiv: este posibil ca imaginile să nu aibă o înălțime universală, numele produselor se pot întinde pe mai multe rânduri și este posibil să aveți sau nu etichete. Practic, se rezumă la asta: nu este posibilă nicio înălțime fixă ​​pentru rând și nici nu știi cu adevărat lățimea. Vremuri amuzante.

La final, am decis să setăm toate diapozitivele (în afară de primul) la visibility: hidden până când caruselul s-a terminat de încărcat, moment în care adăugăm o clasă la carusel pentru a schimba toate diapozitivele pentru a fi vizibile din nou . Acest lucru rezolvă problema de a lua mai întâi înălțime suplimentară.

În plus, am setat inițial flex-shrink: 0 și flex-base: 340px pentru diapozitivele dintr-o casetă flexbox fără împachetare. Acest lucru le face să fie pe o singură linie și oferă o lățime inițială aproximativă pentru diapozitive. Cu acel puzzle rezolvat - și da, a fost la fel de o durere de cap pe cât pare - am adăugat câteva remedieri pentru a păstra loc în care punctele și săgețile să cadă. Cu asta în loc, aproape că nu mai există CLS pentru carusele!

Vedeți Pen [Studiu de caz Jewellerybox (Exemplu #3)](https://codepen.io/smashingmag/pen/vYxpNEK) de Pfenya.

Vedeți Studiul de caz Pen Jewellerybox (Exemplul #3) de Pfenya.

Retrospectiv este 2020

În cele din urmă, au fost o mulțime de mici schimbări de-a lungul mai multor luni care ne-au îmbunătățit scorurile și nu am terminat. Am lucrat în cea mai mare parte cu doi oameni la îmbunătățirea front-end-ului, în timp ce restul echipei s-a concentrat pe îmbunătățirea back-end-ului. Deși probabil a fost puțin mai lent în acest fel, a asigurat că nu a existat nicio suprapunere , iar diferențele de scoruri puteau fi atribuite în mod clar. Unele resurse care au ajutat foarte mult au fost articolele grozave de aici pe Smashing Magazine despre îmbunătățirile proprii ale revistei.

Un scor perfect de 100 pe desktop pentru pagina de pornire. Unele subpagini au scoruri similare.
Un scor perfect de 100 pe desktop pentru pagina de pornire. Unele subpagini au scoruri similare. (Previzualizare mare)

La un moment dat, lucrurile pe care ar trebui să le încerci devin neevidente pentru că nu crezi că ar trebui să facă o mare diferență, dar cândva după aceea realizezi că o fac. Mai mult decât atât, ceea ce ne-a învățat acest proiect din nou este cât de important este să avem în vedere performanța și metricile pentru aceasta încă de la început , de la proiectarea și codificarea prototipului până la implementarea în șabloane. Lucrurile mici neglijate devreme se pot adăuga la munți uriași pe care trebuie să-i urcați mai târziu pentru a-i anula.

Cea mai mare vopsea plină de conținut și prima întârziere de intrare în timp - lent și constant câștigă cursa!
Cea mai mare vopsea plină de conținut și prima întârziere de intrare în timp - lent și constant câștigă cursa! (Previzualizare mare)

Iată câteva dintre aspectele cheie pe care le-am învățat:

  • Optimizarea JavaScript nu este la fel de eficientă precum încărcarea lui la cerere;
  • Optimizarea CSS pare să câștige mai multe puncte decât optimizarea JavaScript;
  • Scrieți clase CSS cu CLS și extragerea CSS-urilor critice în minte;
  • Instrumentele pentru găsirea problemelor CLS nu sunt încă perfecte. Gândește-te în afara cutiei și verifică mai multe instrumente;
  • Evaluați fiecare serviciu terță parte pe care îl integrați pentru dimensiunea fișierului și sincronizarea performanței. Dacă este posibil, respingeți integrarea a tot ceea ce ar încetini totul;
  • Retestați pagina în mod regulat pentru modificările CrUX (și în special CLS);
  • Verificați în mod regulat dacă toate intrările de asistență moștenite sunt încă necesare.
Am făcut progrese bune în „Core Web Vitals”.
Am făcut progrese bune în „Core Web Vitals”. (Previzualizare mare)

Mai avem lucruri de făcut pe lista noastră de îmbunătățiri :

  • Mai avem o mulțime de CSS neutilizate în fișierul principal care ar putea fi eliminate;
  • Am dori să eliminăm complet jQuery. Aceasta va însemna rescrierea unor părți din codul nostru, în special în zona de casă;
  • Mai multe experimente trebuie efectuate despre cum să includă glisoarele externe;
  • Scorurile noastre de puncte mobile ar putea fi mai bune. Vor fi necesare lucrări suplimentare, în special pentru mobil;
  • Imaginile receptive trebuie adăugate pentru toate imaginile produselor;
  • Vom verifica paginile de conținut în mod special pentru îmbunătățirile de care ar putea avea nevoie, în special în jurul CLS;
  • Elementele care utilizează pluginul de restrângere al Bootstrap vor fi înlocuite cu eticheta de details HTML nativă;
  • Dimensiunea DOM trebuie redusă;
  • Vom integra un serviciu terță parte pentru rezultate de căutare mai rapide și mai bune. Aceasta va veni cu o dependență mare de JavaScript pe care va trebui să o integrăm;
  • Vom lucra la îmbunătățirea accesibilității atât prin analiza instrumentelor automate, cât și prin rularea unor teste cu cititoare de ecran și navigare prin tastatură.

Resurse suplimentare

  • „Sfaturi și comenzi rapide de depanare DevTools (Chrome, Firefox, Edge)”, Vitaly Friedman, Smashing Magazine
  • „Unele postări de blog de performanță pe care le-am marcat și le-am citit în ultima vreme”, Chris Coyier, CSS-Tricks
  • „Un ghid aprofundat pentru măsurarea valorilor vitale ale Web-ului”, Barry Pollard, Smashing Magazine
  • „De la CSS semantic la Tailwind: refactorizarea bazei de coduri Netlify UI”, Charlie Gerard și Leslie Cohn-Wein, Netlify
  • „Instrumente de audit CSS”, Iris Lješnjanin, Smashing Magazine
  • „Lucruri pe care le puteți face cu CSS astăzi”, Andy Bell, Smashing Magazine
  • „Cum să îmbunătățești performanța CSS”, Milica Mihajlija, Calibre
  • „Decalajul inegalității performanței mobile, 2021”, Alex Russell
  • „Optimizarea maximă a încărcării imaginilor pentru web în 2021”, Malte Ubl
  • „The Humble <img> Element and Core Web Vitals”, Addy Osmani, Smashing Magazine