Layout Shift causati dalle transizioni CSS
Scopri come trovare e rimuovere le transizioni CSS che causano layout shift

Layout Shift causati dalle transizioni CSS: comprendere e mitigare l'impatto
I Cumulative Layout Shift causati dalle transizioni CSS si verificano spesso nelle prime fasi della fase di caricamento della pagina. Questi layout shift non si verificano in modo costante il che li rende difficili da debuggare.
Table of Contents!
Comprendere le transizioni CSS:
Le transizioni CSS sono uno strumento potente per animare il cambiamento di una proprietà nel tempo. Sono comunemente utilizzate per effetti come dissolvenza, scorrimento e ridimensionamento degli elementi su una pagina web. Gli sviluppatori possono definire gli effetti di transizione specificando la proprietà da transitare, la durata della transizione e la funzione di temporizzazione che governa l'accelerazione della transizione.
Una transizione può avere una proprietà, una durata, una timing-function e un ritardo. Una transizione shorthand si presenta così:
/* property | duration | timing-function | delay */
transition: margin-right 4s ease-in-out 1s; Layout Shift: la conseguenza indesiderata:
I layout shift si verificano quando gli elementi di una pagina web cambiano posizione o dimensione, causando il reflow di altri elementi e lo spostamento del layout complessivo della pagina. Sebbene le transizioni CSS siano progettate per fornire animazioni fluide, possono involontariamente causare layout shift, portando a un'user experience disturbante e sgradevole. Le cause più comuni di layout shift durante le transizioni CSS includono cambiamenti nelle dimensioni, nella posizione o nella visibilità degli elementi.
I Cumulative Layout Shift causati dalle transizioni CSS si verificano generalmente quando un elemento above-the-fold come un menu di navigazione transita dal suo primo stato (senza stile) al suo stato finale (con stile o addirittura nascosto). Questa è solitamente una conseguenza indesiderata di proprietà di transizione troppo generiche. Ad esempio, una voce di menu dovrebbe transitare solo il colore di sfondo e invece della proprietà di transizione 'background-color' è stata scelta 'all'. Questo porterà non solo a una transizione del background ma in alcuni casi anche a una transizione di larghezza, altezza o persino visibilità durante il caricamento della pagina.
Dai un'occhiata all'esempio qui sotto. Questo dimostra un layout shift causato da transizioni CSS che si verificano durante la fase di caricamento di una pagina. Purtroppo vedo questo pattern continuamente e trovare e correggere questo tipo di problemi può essere difficile.
Trovare e correggere le transizioni CSS:
Per trovare e correggere tutti i layout shift causati dalle transizioni CSS dobbiamo eseguire un rapido test. Prima dobbiamo trovare tutte le transizioni CSS. Una volta fatto, dobbiamo assicurarci che la transizione non cambi la posizione (larghezza, altezza, margine, padding, visibilità) di un elemento. Possiamo farlo modificando o disabilitando queste transizioni. Infine possiamo testare l'impatto di queste modifiche e decidere una volta per tutte se le transizioni CSS stanno causando problemi di CLS.
Core Web Vitals tip: I Cumulative Layout Shift causati dalle transizioni CSS si verificano spesso nelle prime fasi della fase di caricamento della pagina. Questi layout shift non si verificano in modo costante, il che li rende difficili da debuggare. Rallentare la rete emulando un dispositivo mobile e disabilitare la cache renderà più facile trovarli!
Passo 1: Trovare le transizioni CSS
Trovare le transizioni CSS può essere fatto manualmente: ispezionare tutti i fogli di stile e cercare la parola 'transition'. Non dovrebbero essere più di 10 minuti di lavoro, ma esiste un modo migliore! Basta incollare questo snippet nella console e premere invio
(() => {
let nodeTable = [];
let nodeArray = [];
// Get the name of the node
function getName(node) {
const name = node.nodeName;
return node.nodeType === 1
? name.toLowerCase()
: name.toUpperCase().replace(/^#/, '');
}
// Get the selector
const getSelector = (node) => {
let sel = '';
try {
while (node && node.nodeType !== 9) {
const el = node;
const part = el.id
? '#' + el.id
: getName(el) +
(el.classList &&
el.classList.value &&
el.classList.value.trim() &&
el.classList.value.trim().length
? '.' + el.classList.value.trim().replace(/\s+/g, '.')
: '');
if (sel.length + part.length > (100) - 1) return sel || part;
sel = sel ? part + '>' + sel : part;
if (el.id) break;
node = el.parentNode;
}
} catch (err) {
// Do nothing...
}
return sel;
};
const getNodesWithTransition = (node) => {
// Get the computed style
let cs = window.getComputedStyle(node);
let tp = cs['transition-property'];
let td = cs['transition-duration'];
// If there is a transition, add it to the table
if (tp !== '' && tp !== 'none' && td != '0s') {
nodeTable.push({ selector: getSelector(node), transition: cs['transition'] });
nodeArray.push(node);
}
// Recursively call this function for each child node
for (let i = 0; i < node.children.length; i++) {
getNodesWithTransition(node.children[i]);
}
}
// find all transitions
getNodesWithTransition(document.body);
// Display the results in the console
console.log('%cReadable table of selectors and their transitions', 'color: red; font-weight: bold;');
console.table(nodeTable);
console.log('%cNodeList for you to inspect (harder to read but more info)', 'color: red; font-weight: bold;');
console.log(nodeArray);
// styles to temporarity override the transitions
let selectors = nodeTable.map((item) => item.selector).join(', ');
console.log('%cSpecific CSS to disable all transitions on this page', 'color: red; font-weight: bold;');
console.log(`<style>${selectors}{transition-property: none !important;}</style>`);
console.log('%cGlobal CSS to disable all transitions on this page (not suggested on production)', 'color: red; font-weight: bold;');
console.log(`<style>*{transition-property: none !important;}</style>`);
})()Vi mostrerà una tabella di tutte le transizioni, gli elementi su cui agiscono e maggiori dettagli sulle transizioni.

Per trovare i layout shift dobbiamo cercare proprietà di transizione come width,height, margin,padding, transform, display e soprattutto all (poiché all include tutte le proprietà di transizione valide)
Passo 2: Modificare le transizioni CSS
Lo snippet JavaScript qui sopra mostrerà tutte le transizioni e fornirà anche codice di esempio su come disabilitarle. Per scopi di test rapido, suggerisco di prendere la strada facile e disabilitare tutte le transizioni con una semplice riga di codice CSS
<style>*{transition-property: none !important;}</style>Ovviamente per ambienti di produzione è necessaria un po' più di finezza. Rimuovete con attenzione solo le proprietà di transizione non necessarie su base selettore per selettore. Ad esempio, cambiate #button{transition: all .2s} in #button{transition: background-color .2s}
Passo 3: Misurare il cambiamento nel layout shift

Altre buone pratiche per le transizioni:
- Preferire l'accelerazione GPU: Utilizzare l'accelerazione GPU per le transizioni CSS può scaricare il carico di rendering dalla CPU alla GPU. Questo può essere ottenuto assicurandosi che le proprietà in transizione siano compatibili con l'accelerazione GPU, come opacity e transform.
- Usare la proprietà "will-change": La proprietà CSS
will-changeinforma il browser che un elemento specifico verrà probabilmente modificato, permettendogli di ottimizzare il rendering di conseguenza. - Garantire dimensioni costanti: Per prevenire layout shift causati da cambiamenti nelle dimensioni, assicuratevi che gli elementi abbiano dimensioni costanti prima e dopo la transizione. Questo può comportare l'impostazione di dimensioni esplicite, l'uso di valori percentuali o l'impiego di tecniche come gli aspect ratio box.
- Ottimizzare le funzioni di temporizzazione: La scelta della funzione di temporizzazione può influire significativamente sulla percezione di fluidità durante una transizione. Prestate attenzione ai pattern di accelerazione e decelerazione e considerate l'uso di
ease-in-outo funzioni cubic bezier personalizzate per un effetto più naturale.
CrUX data is 28 days late.
Google provides data 28 days late. CoreDash provides data in real-time. Debug faster.
- Real-Time Insights
- Faster Debugging
- Instant Feedback

