Migliorare le prestazioni di un negozio online (caso di studio)
Pubblicato: 2022-03-10Ogni sviluppatore front-end sta inseguendo lo stesso Santo Graal delle prestazioni: punteggi verdi in Google Page Speed. I segni tangibili di un lavoro ben fatto sono sempre apprezzati. Come la caccia al Graal, però, devi chiederti se questa è davvero la risposta che stai cercando. Le prestazioni reali per i tuoi utenti e il modo in cui "si sente" il sito Web quando lo stai utilizzando non dovrebbero essere scontate, anche se ti costa uno o due punti in Page Speed (altrimenti, avremmo tutti solo una barra di ricerca e testo).
Lavoro in una piccola agenzia digitale e il mio team lavora principalmente su grandi siti Web e negozi aziendali: la velocità delle pagine entra in discussione a un certo punto, ma di solito a quel punto la risposta è che sarebbe necessaria un'enorme riscrittura per ottenere veramente qualsiasi cosa, uno sfortunato effetto collaterale delle dimensioni e della struttura del progetto nelle società.
Lavorare con Jewellerybox sul suo negozio online è stato per noi un gradito cambio di passo. Il progetto consisteva nell'aggiornamento del software del negozio al nostro sistema open-source e nel rifare da zero il front-end del negozio. Il design è stato realizzato da un'agenzia di design e UX che si è occupata anche del prototipo HTML (basato su Bootstrap 4). Da lì, lo abbiamo incorporato nei modelli e, per una volta, abbiamo avuto anche un cliente ossessionato dalle prestazioni del sito web.
Per il lancio, ci siamo concentrati principalmente sul portare il nuovo design fuori dalla porta, ma una volta che il rilancio del sito Web è stato pubblicato, abbiamo iniziato a concentrare la nostra attenzione sul trasformare i punteggi rossi e arancioni in verdi. È stato un viaggio di più mesi pieno di decisioni difficili, con molte discussioni su quali ottimizzazioni valesse la pena perseguire. Oggi, il sito Web è molto più veloce e si posiziona in alto in varie vetrine e benchmark. In questo articolo, metterò in evidenza alcuni dei lavori che abbiamo svolto e come siamo riusciti a raggiungere la nostra velocità.
I negozi online sono un po' diversi
Prima di entrare nei dettagli, prendiamoci un momento per parlare di come i negozi online sono diversi da molti altri siti Web (se lo sai già, ci incontreremo con te nella prossima sezione). Quando si parla di un sito e-commerce le pagine principali che si hanno sono:
- la home page (e le pagine di “contenuto”),
- categoria e pagine di ricerca,
- pagine dei dettagli del prodotto,
- il carrello e la cassa (ovviamente).
Per questo articolo, ci concentreremo sui primi tre e sugli adeguamenti delle prestazioni per questi. La cassa è la sua stessa bestia. Lì avrai un sacco di JavaScript extra e logica di back-end per calcolare i prezzi, oltre a diverse chiamate di servizio per ottenere il fornitore di spedizioni appropriato e stime dei prezzi in base al paese in cui viene spedito.
Questo ovviamente si aggiunge alla convalida dei campi dei moduli necessari per registrare gli indirizzi di fatturazione e spedizione. Aggiungi a ciò il drop-in del fornitore di servizi di pagamento e avrai tu stesso alcune pagine che nessuno vorrà toccare una volta che sono state adeguatamente testate e funzionano.
Qual è la prima cosa a cui pensi quando immagini un negozio online? Immagini : tantissime immagini di prodotti. Sono praticamente ovunque e domineranno il tuo design. Inoltre, vorrai mostrare molti prodotti per convincere le persone ad acquistare da te, quindi è un carosello. Ma aspetta! Le persone fanno clic sui prodotti in esso contenuti? Possiamo scoprirlo mettendo un po' di tracking sul carosello. Se lo seguiamo, possiamo ottimizzarlo! E all'improvviso, sulle nostre pagine abbiamo dei caroselli di prodotti esterni basati sull'intelligenza artificiale.
Il fatto è che un carosello non sarà l'ultimo elemento di penalizzazione della velocità che aggiungi alla pagina per mostrare più prodotti nella speranza di attirare più vendite. Naturalmente, un negozio ha bisogno di elementi interattivi , che si tratti di zoom dell'immagine del prodotto, alcuni video, un conto alla rovescia per la scadenza di spedizione odierna o una finestra di chat per entrare in contatto con l'assistenza clienti.
Tutti questi aspetti sono molto importanti quando si misurano le conversioni direttamente come entrate . Inoltre, ogni pochi mesi, qualcuno del team individuerà alcune nuove interessanti funzionalità che potrebbero essere aggiunte, e quindi la complessità e JavaScript iniziano ad accumularsi, anche se hai iniziato con le migliori intenzioni per mantenerlo snello.
E mentre di solito puoi memorizzare nella cache l'intera pagina di un articolo, lo stesso non vale per molte pagine ed elementi del negozio. Alcuni sono specifici dell'utente, come il carrello nell'intestazione o nella lista dei desideri e, a causa della natura personale dei dati, non dovrebbero mai essere memorizzati nella cache. Inoltre, se hai beni fisici, hai a che fare con l'inventario in tempo reale: soprattutto durante la corsa natalizia, avrai bisogno che le informazioni sull'inventario siano precise e aggiornate; quindi, avrai bisogno di una strategia di memorizzazione nella cache più complessa che ti consenta di memorizzare nella cache parti della pagina e combinare tutto insieme durante il rendering lato server.
Ma anche nelle fasi di progettazione, le trappole attendono. In un progetto, e spesso anche nella fase di prototipazione, lavorerai con nomi e descrizioni di prodotti finemente realizzati, tutti di lunghezza quasi uniforme e immagini di prodotto ideali. Hanno un aspetto fantastico! L'unico problema? In realtà, le informazioni sul prodotto possono essere di lunghezza molto diversa, il che può rovinare il tuo design. Con diverse migliaia di prodotti, non puoi controllarli tutti.
Pertanto, è utile se i designer o le persone che eseguono il prototipo testano con stringhe molto corte e molto lunghe per assicurarsi che il design si adatti ancora. Allo stesso modo, avere le informazioni visualizzate due volte nell'HTML, una per desktop e una per dispositivi mobili, può essere un grosso problema per un negozio, soprattutto se si tratta di informazioni complesse come i dettagli del prodotto, il carrello o le sfaccettature per i filtri su una categoria di prodotto pagina. Mantenerli sincronizzati è difficile da fare, quindi per favore aiuta un collega sviluppatore e non farlo.
Un'altra cosa che non dovrebbe mai essere un ripensamento e dovrebbe essere incorporata dalla fase del prototipo in poi è l'accessibilità. Diversi strumenti disponibili possono aiutarti con alcune delle nozioni di base, dall'avere testo alternativo per tutte le immagini e icone con una funzione, al contrasto del colore, al sapere quali attributi ARIA usare dove (e quando non farlo). Incorporarlo dall'inizio è molto più semplice che in seguito e consente a tutti di godersi il sito Web su cui stai lavorando.
Ecco un consiglio: se non hai visto persone usare uno screen reader o navigare solo con una tastiera, i video su questo possono essere facilmente trovati su YouTube. Cambierà la tua comprensione di questi argomenti.
Torna alle prestazioni: perché è così importante migliorare nuovamente le prestazioni di un negozio? La risposta ovvia è che vuoi che le persone comprino da te . Esistono diversi modi in cui puoi influire su questo e la velocità del tuo sito Web è grande. Gli studi dimostrano che ogni secondo aggiuntivo di tempo di caricamento ha un impatto significativo sul tasso di conversione. Inoltre, la velocità della pagina è un fattore di ranking per la ricerca e anche per i tuoi annunci Google. Quindi, il miglioramento delle prestazioni avrà un effetto tangibile sui profitti.
Cose pratiche che abbiamo fatto
Alcuni colli di bottiglia delle prestazioni sono facili da identificare, ma un miglioramento completo è un viaggio più lungo, con molti colpi di scena. Abbiamo iniziato con tutte le solite cose, come ricontrollare la memorizzazione nella cache delle risorse, vedere cosa potevamo precaricare o caricare in modo asincrono, assicurandoci di utilizzare HTTP/2 e TLSv1.3. Molti di questi sono trattati nell'utile panoramica di CSS-Tricks e Smashing Magazine offre un'ottima lista di controllo PDF.
Per prima cosa: cose caricate su tutte le pagine
Parliamo di risorse, e non solo di CSS o JavaScript (di cui parleremo più avanti). Abbiamo iniziato esaminando le cose condivise su più schermi, ognuno dei quali può avere un impatto. Solo dopo ci siamo concentrati sui tipi di pagina e sui problemi che li riguardano. Alcuni elementi comuni erano i seguenti.
Caricamento delle icone
Come in tanti siti Web, utilizziamo diverse icone nel nostro design. Il prototipo è arrivato con alcune icone personalizzate che erano simboli SVG incorporati. Questi sono stati archiviati come un grande tag svg
nell'intestazione HTML della pagina, con un simbolo per ciascuna delle icone che è stato poi utilizzato come svg
collegato nel corpo dell'HTML. Questo ha il piacevole effetto di renderli direttamente disponibili al browser quando il documento viene caricato, ma ovviamente il browser non può memorizzarli nella cache per l'intero sito web.
Quindi abbiamo deciso di spostarli in un file SVG esterno e precaricarlo. Inoltre, abbiamo incluso solo le icone che effettivamente utilizziamo. In questo modo, il file può essere memorizzato nella cache sul server e nel browser e non sarà necessario interpretare SVG superflui. Supportiamo anche l'uso di Font Awesome sulla pagina (che carichiamo tramite JavaScript), ma lo carichiamo su richiesta (aggiungendo un piccolo script che controlla eventuali tag <i>
e quindi caricando Font Awesome JavaScript per ottenere qualsiasi SVG icone che trova). Poiché ci atteniamo alle nostre icone above the fold, possiamo eseguire l'intero script dopo il caricamento del DOM.
Usiamo anche le emoji in alcuni punti per le icone colorate, qualcosa a cui nessuno di noi ha davvero pensato ma che la nostra editor di contenuti, Daena, ha chiesto e che sono un ottimo modo per mostrare le icone senza alcun effetto negativo sulle prestazioni (l'unico avvertimento è i diversi design su diversi sistemi operativi).
Caricamento dei caratteri
Come su tanti altri siti Web, utilizziamo i caratteri Web per le nostre esigenze tipografiche. Il design richiede due caratteri nel corpo ( Josefin Sans in due pesi), uno per i titoli ( Nixie One ) e uno per il testo con uno stile speciale ( Moonstone Regular ). Fin dall'inizio, li abbiamo archiviati localmente, con una rete di distribuzione dei contenuti (CDN) per le prestazioni, ma dopo aver letto il meraviglioso articolo di Simon Hearne sull'evitare i cambiamenti di layout con il caricamento dei caratteri, abbiamo provato a rimuovere la versione in grassetto e a utilizzare quella normale.
Nei nostri test, la differenza visiva era così piccola che nessuno dei nostri tester è stato in grado di distinguere senza vederli entrambi contemporaneamente. Quindi, abbiamo abbassato il peso del carattere . Mentre lavoravamo su questo articolo e preparavamo un aiuto visivo per questa sezione, ci siamo imbattuti in differenze maggiori tra i browser basati su Chromium su Mac e quelli basati su WebKit su schermi ad alta risoluzione (yay, complessità!). Ciò ha portato a un altro giro di discussioni su cosa dovremmo fare.
Dopo un po' di avanti e indietro, abbiamo deciso di mantenere il grassetto falso e di utilizzare -webkit-text-stroke: 0.3px
per aiutare quei browser particolari. La differenza rispetto all'utilizzo del peso del carattere separato effettivo è lieve, ma non sufficiente per il nostro caso d'uso, in cui non utilizziamo quasi nessun carattere in grassetto, solo una manciata di parole alla volta (scusate, appassionati di caratteri).
Inoltre, diversi prodotti possono essere personalizzati con incisioni . Queste incisioni possono essere eseguite in più caratteri e per alcuni offriamo un'anteprima con il carattere applicato. Per questi, scarichiamo il carattere su richiesta quando viene scelto nel selettore del carattere a discesa. Le anteprime nel menu a discesa sono immagini di esempio di come appare il carattere. Questo ci evita di dover scaricare 10 o più file di font aggiuntivi.
Supporto legacy
Un giorno, CSS-Tricks mi ha sorpreso con un articolo su “Come Favicon nel 2021”. Stavamo usando ogni dimensione dell'icona del tocco nel mondo: l'articolo mi ha fatto rivalutare ciò di cui abbiamo effettivamente bisogno e mi ha mostrato che a volte ciò che era vero fino a pochi anni fa potrebbe non essere più necessario. Sulla base dell'articolo, abbiamo limitato i nostri elenchi di favicon e icone touch alle versioni consigliate.
Allo stesso modo, abbiamo anche convertito un font che avevamo solo come versione WOFF in WOFF2 , che è molto più piccolo, e abbiamo deciso di fornire WOFF2 per i font (con WOFF che rimane come fallback). E abbiamo eliminato le direttive CSS che non sono più necessarie.
Caricamento pigro e su richiesta
Diverse metriche si concentrano sul tempo dopo il quale gli utenti possono interagire con la pagina. La logica impone che avere meno elementi da caricare significa che questo punto verrà raggiunto prima. Per tenere conto di ciò, è importante chiedersi quali parti della pagina sono essenziali e di cui l'utente avrà bisogno solo in seguito. Abbiamo attraversato un sacco di dibattiti e tentativi ed errori su questo.
La cascata dell'attività di rete ha aiutato molto qui, ma anche il pensiero dei flussi di utenti. Ad esempio, l'immagine del prodotto ingrandita può essere caricata la prima volta che un utente interagisce con l'immagine del prodotto e le immagini nel piè di pagina di solito non vengono visualizzate above the fold e possono essere caricate in un secondo momento. Se sei preoccupato per i rallentamenti, puoi comunque lavorare con il precaricamento delle risorse.
Una cosa che abbiamo notato molto presto è stato il grande impatto del client di chat. Erano oltre 500 KB di JavaScript da solo e, anche se sfortunatamente non ho più un grafico, anche il caricamento è stato lento. Anche se JavaScript è stato impostato per il caricamento in modo asincrono, Google lo ha incluso nelle misurazioni time-to-interactive.
Non siamo stati in grado di tracciare completamente il motivo per cui questo era il caso, ma tra questo e le sue dimensioni, abbiamo iniziato a cercare alternative, invece di cercare di riparare qualcosa su cui avevamo un controllo limitato. Abbiamo convinto Jewellerybox a provare invece un widget di chat open source self-hosted , che ci dà un maggiore controllo su come viene caricato e che è anche molto più piccolo. Per migliorarlo ulteriormente, carichiamo inizialmente solo l'icona della chat; il resto viene caricato quando si fa clic per aprirlo.
Il carosello invisibile di terze parti
Jewellerybox ha voluto provare un servizio di terze parti che utilizza l'intelligenza artificiale per migliorare la personalizzazione del prodotto nei caroselli su più pagine. Abbiamo deciso di chiamare la sua API dal back-end per questo, in modo da avere un maggiore controllo su ciò che viene caricato (senza grandi dipendenze JavaScript) e su quanto tempo aspettiamo una risposta dal loro servizio (con alcuni fallback definiti). Per questo motivo, i caroselli si caricano allo stesso modo di quelli non personalizzati e possono essere memorizzati nella cache anche con una chiave cache univoca.
Tuttavia, c'è uno svantaggio: ciò significa che il rendering della pagina iniziale sul lato server potrebbe essere più lento a meno che non venga memorizzato nella cache. Per questo motivo, stiamo attualmente lavorando su modi alternativi per inserire i risultati dopo che la pagina è stata caricata e inizialmente renderizzando un segnaposto.
Secondo: ottimizzazione di JavaScript: una battaglia in salita contro nemici esterni
Il carosello ci porta alla seconda grande area su cui ci siamo concentrati: JavaScript. Abbiamo verificato il JavaScript che avevamo e la maggior parte proviene da librerie per attività diverse, con pochissimo codice personalizzato. Abbiamo ottimizzato il codice che avevamo scritto noi stessi, ma ovviamente c'è solo così tanto che puoi fare se è solo una frazione del tuo codice complessivo: i grandi vantaggi risiedono nelle librerie.
L'ottimizzazione delle cose nelle biblioteche o l'eliminazione di parti che non ti servono è, con ogni probabilità, una commissione stupida. Non sai davvero perché ci sono alcune parti e non sarai mai in grado di aggiornare di nuovo la libreria senza molto lavoro manuale. Con questo in mente, abbiamo fatto un passo indietro e abbiamo esaminato quali biblioteche utilizziamo e per cosa ne abbiamo bisogno , e abbiamo studiato per ognuna se esiste un'alternativa più piccola o più veloce che si adatta altrettanto bene alle nostre esigenze.
In molti casi c'era! Ad esempio, abbiamo deciso di sostituire la libreria di scorrimento Slick con GliderJS, che ha meno funzioni ma tutte quelle di cui abbiamo bisogno, inoltre è più veloce da caricare e ha un supporto CSS più moderno! Inoltre, abbiamo rimosso molte delle librerie autonome dal file JavaScript principale e abbiamo iniziato a caricarle su richiesta.
Poiché stiamo usando Bootstrap 4, stiamo ancora includendo jQuery per il progetto ma stiamo lavorando per sostituire tutto con implementazioni native. Per Bootstrap stesso, esiste una versione bootstrap.native su GitHub senza la dipendenza jQuery che ora utilizziamo. È di dimensioni ridotte e funziona più velocemente. Inoltre, generiamo due versioni del nostro file JavaScript principale: una senza polyfill e una con loro inclusi, e scambiamo la versione con loro quando il browser ne ha bisogno, consentendoci di fornire una versione principale semplificata alla maggior parte delle persone. Abbiamo testato un servizio "polyfill-on-demand", ma le prestazioni non hanno soddisfatto le nostre aspettative.
Un'ultima cosa sull'argomento di jQuery. Inizialmente, l'abbiamo caricato dal nostro server. Abbiamo notato miglioramenti delle prestazioni sul nostro sistema di test durante il caricamento tramite la CDN di Google, ma Page Speed Insights si è lamentato delle prestazioni (mi chiedo chi potrebbe risolverlo), quindi abbiamo testato di nuovo l'hosting noi stessi e in produzione è stato effettivamente più veloce a causa del CDN che usiamo.
Lezione appresa : un ambiente di test non è un ambiente di produzione e le correzioni per uno potrebbero non essere valide per l'altro.
Terzo: immagini: formati, dimensioni e tutto quel jazz
Le immagini sono una parte enorme di ciò che rende un negozio online. Una pagina di solito avrà diverse dozzine di immagini, anche prima di contare le diverse versioni per i diversi dispositivi. Il sito web di Jewellerybox esiste da quasi 10 anni e molti prodotti sono disponibili per la maggior parte del tempo, quindi le immagini dei prodotti originali non sono uniformi per dimensioni e stile e anche il numero di scatti del prodotto può variare.
Idealmente, vorremmo offrire immagini reattive per diverse dimensioni di visualizzazione e densità di visualizzazione in formati moderni, ma qualsiasi modifica dei requisiti significherebbe molto lavoro di conversione da fare. Per questo motivo, attualmente utilizziamo una dimensione ottimizzata delle immagini dei prodotti, ma non abbiamo immagini reattive per loro. Aggiornamento che è sulla road map ma non banale. Le pagine di contenuto offrono maggiore flessibilità e qui generiamo e utilizziamo dimensioni diverse e includiamo sia i formati WebP che quelli di riserva.
Avere così tante immagini aggiunge molto peso al carico utile iniziale. Quindi, quando e come caricare le immagini è diventato un argomento enorme. Il caricamento lento suona come la soluzione, ma se applicato universalmente può rallentare le immagini inizialmente visibili, piuttosto che caricarle direttamente (o almeno sembra così per l'utente). Per questo motivo, abbiamo optato per una combinazione di caricamento diretto dei primi e lazy-loading del resto, utilizzando una combinazione di lazy-loading nativo e uno script.
Per il logo del sito utilizziamo un file SVG, per il quale abbiamo ricevuto una versione iniziale dal client. Il logo è un carattere intricato in cui mancano parti delle lettere, poiché sarebbero in una stampa imperfetta fatta a mano. In grandi dimensioni, dovresti mostrare i dettagli, ma sul sito Web non lo usiamo mai sopra i 150 per 30 pixel. Il file originale aveva una dimensione di 192 KB, non enorme ma nemmeno super piccolo. Abbiamo deciso di giocare con l'SVG e di ridurne i dettagli, e abbiamo finito con una versione decompressa con una dimensione di 40 KB. Non vi è alcuna differenza visiva nelle dimensioni del display che utilizziamo.
Ultimo ma sicuramente non meno importante: CSS
CSS critico
I CSS sono molto presenti nel rapporto sull'esperienza utente di Chrome (CrUX) di Google e sono presenti anche nel rapporto e nei consigli di Google Page Speed Insights. Una delle prime cose che abbiamo fatto è stata definire alcuni CSS critici, che carichiamo direttamente nell'HTML in modo che siano disponibili per il browser il prima possibile: questa è la tua arma principale per combattere i cambiamenti di layout dei contenuti (CLS). Abbiamo optato per una combinazione di estrazione automatizzata del CSS critico basato su una pagina prototipo e un meccanismo con cui possiamo definire i nomi delle classi da estrarre (comprese tutte le sottoregole). Lo facciamo separatamente per gli stili generali, gli stili di pagina del prodotto e gli stili di categoria aggiunti ai rispettivi tipi di pagina.
Qualcosa che abbiamo imparato da questo e che ha causato alcuni bug nel mezzo è che dobbiamo stare attenti che l'ordine dei CSS non venga modificato da questo. Tra persone diverse che scrivono il codice, qualcuno che aggiunge un override più avanti nel file e uno strumento automatico che estrae cose, può diventare disordinato.
Dimensioni esplicite contro CLS
Per me, CLS è qualcosa che Google ha tirato fuori dal cilindro, e ora tutti dobbiamo affrontarlo e avvolgerci le nostre teste collettive. Mentre prima potevamo semplicemente lasciare che i contenitori prendessero le loro dimensioni dagli elementi al loro interno, ora il caricamento di quegli elementi può alterare le dimensioni della scatola. Con questo in mente, abbiamo utilizzato la scheda "Prestazioni" negli Strumenti per sviluppatori e l'utilissimo generatore di GIF Layout Shift per vedere quali elementi stanno causando CLS. Da lì, abbiamo esaminato non solo gli elementi stessi, ma anche i loro genitori e abbiamo analizzato le proprietà CSS che avrebbero avuto un impatto sul layout. A volte siamo stati fortunati, ad esempio, il logo necessitava solo di una dimensione esplicita impostata sul dispositivo mobile per evitare uno spostamento del layout, ma altre volte la lotta era reale.
Suggerimento per professionisti: a volte uno spostamento non è causato dall'elemento apparente, ma dall'elemento che lo precede. Per identificare possibili colpevoli, concentrati sulle proprietà che cambiano in termini di dimensioni e spaziatura. La domanda fondamentale da porsi è: cosa potrebbe causare lo spostamento di questo blocco?
Poiché ci sono così tante immagini sulla pagina, anche far sì che si comportino correttamente con CLS ci ha causato un po' di lavoro. Barry Pollard ce lo ricorda giustamente nel suo articolo, "Impostare altezza e larghezza sulle immagini è di nuovo importante". Abbiamo trascorso molto tempo a capire i valori di larghezza e altezza corretti (più le proporzioni) per le nostre immagini in ogni caso per aggiungerle nuovamente all'HTML. Di conseguenza, non c'è più alcun cambiamento di layout per le immagini perché il browser ottiene le informazioni in anticipo.
Il caso del misterioso punteggio CLS
Dopo aver rimosso molti dei grandi problemi di CLS nella parte superiore della pagina, abbiamo raggiunto un ostacolo. A volte (non sempre) guardando Page Speed o Lighthouse, abbiamo ottenuto un punteggio CLS superiore a 0,3, ma mai nella scheda "Prestazioni". Il Generatore GIF di spostamento layout a volte lo mostrava, ma sembrava che l' intero contenitore della pagina si stesse muovendo .
Con la limitazione della rete e della CPU abilitata, l'abbiamo finalmente vista negli screenshot! L'intestazione sui dispositivi mobili stava crescendo di 2 pixel in altezza a causa degli elementi al suo interno. Poiché l'intestazione è comunque un'altezza fissa sui dispositivi mobili, abbiamo optato per la semplice correzione e abbiamo aggiunto un'altezza esplicita: custodia chiusa. Ma ci è costato un sacco di nervi e mostra che gli strumenti qui sono ancora molto imprecisi.
Questo non funziona - Rifacciamolo!
Come tutti sappiamo, i punteggi per dispositivi mobili sono molto più severi per Page Speed che per desktop e un'area in cui erano particolarmente negativi per noi era sulle pagine dei prodotti. Il punteggio CLS era alle stelle e la pagina presentava anche problemi di prestazioni (molti caroselli, schede ed elementi non memorizzabili nella cache lo faranno). A peggiorare le cose, il layout della pagina significava che alcune informazioni venivano mescolate o aggiunte due volte.
Su desktop, abbiamo fondamentalmente due colonne per il contenuto:
- Colonna A : Il carosello di foto del prodotto, a volte seguito da citazioni di blogger, seguito da un layout a schede con informazioni sul prodotto.
- Colonna B : il nome del prodotto, il prezzo, la descrizione e il pulsante "aggiungi al carrello".
- Riga C : Il carosello di prodotti di prodotti simili.
Sui dispositivi mobili, tuttavia, il carosello delle foto del prodotto doveva venire prima, quindi la colonna B, quindi il layout a schede dalla colonna A. A causa di ciò, alcune informazioni erano duplicate nell'HTML, essendo controllate dal display: none
e l'ordine era in corso commutato con il flex: order
. Sicuramente funziona, ma non va bene per i punteggi CLS perché praticamente tutto deve essere riordinato.
Ho deciso per un semplice esperimento in CodePen: potrei ottenere lo stesso layout di base delle scatole su desktop e su dispositivi mobili ripensando all'HTML e utilizzando display: grid
invece di flexbox, e ciò mi consentirebbe semplicemente di riorganizzare le aree della griglia secondo necessità? Per farla breve, ha funzionato e ha risolto il CLS, e ha il vantaggio aggiuntivo che il nome del prodotto ora arriva molto prima nell'HTML rispetto a prima: una vittoria SEO aggiuntiva!
Hacking di un carosello per CLS
La parola "carosello" è già comparsa diverse volte, e con buone ragioni. Non solo abbiamo cambiato la libreria del carosello che utilizziamo (e modificato il comportamento di caricamento delle immagini in essa contenute), ma abbiamo anche dovuto gestirla per CLS perché abbiamo diverse pagine su cui il carosello è above the fold e, quindi, potrebbe avere un grande impatto sui punteggi di velocità.
Abbiamo iniziato caricando il carosello in un secondo momento per ridurre il time-to-interactive , ma ciò ha causato un ritardo visibile fino all'attivazione di JavaScript e allo spostamento delle diapositive dall'essere sotto l'altra all'essere in una riga. Abbiamo provato molti modi per scrivere il CSS per evitare che ciò accada e per mantenere tutto su una riga, incluso nascondere l'intero carosello fino al termine del caricamento. Niente ci ha dato il tipo di soluzione che avremmo voluto vedere visitando un negozio come utente.
Ci scusiamo per questo breve sfogo, ma in realtà i caroselli di prodotti e categorie sono la tempesta perfetta di elementi flessibili in un negozio reattivo: le immagini potrebbero non avere un'altezza universale, i nomi dei prodotti potrebbero estendersi su più righe e potresti avere o meno etichette. Fondamentalmente, si riduce a questo: non è possibile un'altezza fissa per la riga e non conosci nemmeno la larghezza. Momenti divertenti.
Alla fine, abbiamo deciso di impostare tutte le diapositive (a parte la prima) in visibility: hidden
fino al termine del caricamento del carosello, a quel punto aggiungiamo una classe al carosello per modificare tutte le diapositive in modo che siano nuovamente visibili . Questo risolve il problema di occupare un'altezza aggiuntiva all'inizio.
Inoltre, impostiamo inizialmente flex-shrink: 0
e flex-base: 340px
per le diapositive in una flexbox senza avvolgimento. Ciò fa sì che si trovino su un'unica riga e fornisca una larghezza iniziale approssimativa per le diapositive. Con quell'enigma risolto - e sì, è stato un mal di testa come sembra - abbiamo aggiunto alcune correzioni per lasciare spazio in cui i punti e le frecce cadevano. Con quello in atto, non c'è quasi più CLS per i caroselli!
Il senno di poi è 20 ⁄ 20
Alla fine, sono stati molti piccoli cambiamenti in diversi mesi che hanno migliorato i nostri punteggi e non abbiamo finito. Abbiamo lavorato principalmente con due persone sui miglioramenti dell'avantreno, mentre il resto del team si è concentrato sul miglioramento del retrotreno. Sebbene fosse probabilmente un po' più lento in questo modo, assicurava che non ci fossero sovrapposizioni e che le differenze nei punteggi potessero essere chiaramente attribuite. Alcune risorse che hanno aiutato molto sono stati gli ottimi articoli qui su Smashing Magazine sui miglioramenti della rivista.
Ad un certo punto, le cose che dovresti provare diventano non ovvie perché pensi che non dovrebbero fare una grande differenza, ma qualche volta ti rendi conto che lo fanno. Inoltre, ciò che questo progetto ci ha insegnato ancora una volta è quanto sia importante avere in mente le prestazioni e le metriche fin dall'inizio , dall'ideazione del design e dalla codifica del prototipo all'implementazione nei modelli. Piccole cose trascurate all'inizio possono sommarsi a enormi montagne che devi scalare in seguito per annullare.
Ecco alcuni degli aspetti chiave che abbiamo imparato:
- L'ottimizzazione di JavaScript non è efficace quanto il caricamento su richiesta;
- L'ottimizzazione dei CSS sembra guadagnare più punti rispetto all'ottimizzazione di JavaScript;
- Scrivere classi CSS con CLS ed estrazione di CSS critici in mente;
- Gli strumenti per trovare problemi CLS non sono ancora perfetti. Pensa fuori dagli schemi e seleziona diversi strumenti;
- Valuta ogni servizio di terze parti che integri in base alle dimensioni dei file e ai tempi delle prestazioni. Se possibile, respingi l'integrazione di tutto ciò che rallenterebbe tutto;
- Ritesta la tua pagina regolarmente per le modifiche CrUX (e soprattutto CLS);
- Controlla regolarmente se tutte le voci di supporto legacy sono ancora necessarie.
Abbiamo ancora cose nella nostra lista di miglioramenti da apportare:
- Abbiamo ancora molti CSS inutilizzati nel file principale che potrebbero essere rimossi;
- Vorremmo rimuovere completamente jQuery. Ciò significherà riscrivere parti del nostro codice, specialmente nell'area checkout;
- Devono essere condotti ulteriori esperimenti su come includere i cursori esterni;
- I nostri punteggi in punti mobili potrebbero essere migliori. Sarà necessario ulteriore lavoro soprattutto per i dispositivi mobili;
- È necessario aggiungere immagini reattive per tutte le immagini dei prodotti;
- Controlleremo le pagine di contenuto in modo specifico per i miglioramenti di cui potrebbero aver bisogno, in particolare per quanto riguarda CLS;
- Gli elementi che utilizzano il plug-in di compressione di Bootstrap verranno sostituiti con il tag dei
details
HTML nativo; - La dimensione del DOM deve essere ridotta;
- Integreremo un servizio di terze parti per risultati di ricerca migliori e più rapidi. Ciò verrà fornito con una grande dipendenza da JavaScript che dovremo integrare;
- Lavoreremo per migliorare l'accessibilità sia esaminando gli strumenti automatizzati sia eseguendo alcuni test con lettori di schermo e la navigazione da tastiera noi stessi.
Ulteriori risorse
- "Suggerimenti e scorciatoie per il debug di DevTools (Chrome, Firefox, Edge)" Vitaly Friedman, Smashing Magazine
- "Alcuni post del blog sulle prestazioni che ho aggiunto ai preferiti e letti di recente", Chris Coyier, CSS-Tricks
- "Una guida approfondita per misurare i vitali web principali", Barry Pollard, Smashing Magazine
- "Dal CSS semantico a Tailwind: refactoring della base di codice dell'interfaccia utente di Netlify", Charlie Gerard e Leslie Cohn-Wein, Netlify
- "Strumenti di auditing CSS", Iris Lješnjanin, Smashing Magazine
- "Cose che puoi fare con CSS oggi", Andy Bell, Smashing Magazine
- "Come migliorare le prestazioni CSS", Milica Mihajlija, Calibre
- "Il divario di disuguaglianza delle prestazioni mobili, 2021", Alex Russell
- "Ottimizzazione massima del caricamento delle immagini per il Web nel 2021", Malte Ubl
- "L'umile elemento
<img>
e i principali elementi vitali del Web", Addy Osmani, Smashing Magazine