Proprietà CSS will-change
Usa la proprietà CSS will-change per indicare come un elemento cambierà in futuro. Scopri la proprietà e prova esempi pratici.
La proprietà will-change fornisce al browser un suggerimento su come ci si aspetta che un elemento cambi nel prossimo futuro, così il browser può impostare le ottimizzazioni necessarie prima che il cambiamento avvenga — invece di affannarsi a ottimizzare nel fotogramma stesso in cui il cambiamento ha inizio.
Questa pagina illustra cosa fa will-change, quando (e quando non) utilizzarla, i valori accettati, un esempio eseguibile e le insidie che la rendono facile da usare in modo improprio.
Perché esiste will-change
Proprietà come transform e opacity sono economiche da animare perché il browser può promuovere l'elemento al proprio layer di compositing (una superficie separata che la GPU può spostare, dissolvere o ridimensionare senza ridisegnare il resto della pagina). La creazione di quel layer, tuttavia, richiede tempo e memoria. Se il browser scopre di aver bisogno di un layer solo nel momento in cui un'animazione inizia, il primo fotogramma può risultare discontinuo.
will-change ti permette di dire al browser in anticipo quali proprietà stanno per cambiare, così può preparare il layer per tempo e mantenere l'animazione fluida fin dal primo fotogramma.
I valori sono separati da virgole. La proprietà will-change accetta questi valori: auto, un <custom-ident> come il nome di una proprietà (transform, opacity, scroll-position, …), initial, inherit o unset.
Questa proprietà deve essere utilizzata con cautela. Browser diversi la gestiscono in modo diverso e un uso eccessivo può indurre il browser a ignorarla. L'abuso può anche forzare layer di compositing non necessari, aumentando l'uso della memoria e peggiorando le prestazioni.
Utilizzo corretto della proprietà will-change
- Non applicarla a troppi elementi. Ogni suggerimento
will-changepuò costringere il browser a mantenere attivo un layer di compositing, il che consuma memoria. Se si suggerisce su centinaia di elementi, si rischia di rallentare la pagina invece di accelerarla. - Aggiungila e rimuovila tramite script, attorno al cambiamento. Imposta
will-changepoco prima del cambiamento (ad esempio sumouseenterofocus), poi rimuovila non appena l'animazione termina, così il browser può rilasciare il layer. - Non usarla come ottimizzazione prematura. Se una pagina è già animata in modo fluido, lasciala così com'è. Ricorri a
will-changesolo per risolvere un problema di prestazioni misurato — è un'ultima risorsa, non un'impostazione predefinita. - Dai al browser il tempo di prepararsi. Lo scopo di
will-changeè avvisare il browser prima del cambiamento. Impostarla nello stesso fotogramma in cui inizia l'animazione vanifica lo scopo. - Tieni presente che può influire sul rendering. I valori che creano un contesto di sovrapposizione (come
will-change: opacityowill-change: transform) possono modificare il modo in cui l'elemento si sovrappone ai suoi fratelli, proprio come farebbe l'effettiva impostazione di quelle proprietà.
| Valore iniziale | auto |
|---|---|
| Si applica a | Tutti gli elementi. |
| Ereditata | No. |
| Animabile | No. |
| Versione | CSS Transitions Module Level 1 |
| Sintassi DOM | object.style.willChange = "transform"; |
Nota: in JavaScript, il nome della proprietà usa il camelCase (willChange), mentre la proprietà CSS usa i trattini (will-change).
Sintassi
Valori CSS di will-change
will-change: auto | <custom-ident> | initial | inherit | unset;Esempio della proprietà will-change:
Esempio di codice CSS will-change
<!DOCTYPE html>
<html>
<head>
<title>The title of the document</title>
<style>
.circle {
width: 50px;
height: 50px;
transform: translate(50px, 0px);
border-radius: 30px;
}
.circle.blue {
background: #1c87c9;
will-change: transform;
}
.circle.green {
background: #8ebf42;
}
</style>
</head>
<body>
<h2>Will-change property example</h2>
<div class="circle green"></div>
<div class="circle blue"></div>
<div class="circle green"></div>
<div class="circle blue"></div>
<div class="circle green"></div>
<script>
const circles = document.getElementsByClassName("circle blue");
function update(t) {
for (let i = 0; i < circles.length; i++) {
const xpos = Math.sin(t / 1000 + 1000 * i) * 50 + 50;
circles[i].style.transform = "translate(" + xpos + "px, 0px)";
}
window.requestAnimationFrame(update);
}
update();
</script>
</body>
</html>Impostare e rimuovere will-change con script
Il pattern consigliato è aggiungere il suggerimento subito prima di un'interazione e rimuoverlo in seguito, così il browser mantiene il layer solo quando è necessario:
.card {
transition: transform 0.3s;
}
/* Hint the browser only while the user hovers. */
.card:hover {
will-change: transform;
transform: scale(1.05);
}Per animazioni di lunga durata o gestite tramite JavaScript, si può attivare e disattivare via codice:
const el = document.querySelector(".card");
// Prepare ahead of the change.
el.addEventListener("mouseenter", () => {
el.style.willChange = "transform";
});
// Release the optimization once it's no longer needed.
el.addEventListener("animationend", () => {
el.style.willChange = "auto";
});Valori
| Valore | Descrizione |
|---|---|
| auto | Deve essere applicata l'ottimizzazione standard del browser. |
<custom-ident> | Specifica la proprietà CSS che si prevede cambi o venga animata sull'elemento nel prossimo futuro. Se la proprietà è una shorthand, le modifiche si espanderanno a tutte le sue proprietà longhand. |
| initial | Fa sì che la proprietà utilizzi il suo valore predefinito. |
| inherit | Eredita la proprietà dall'elemento padre. |
| unset | Reimposta la proprietà al suo valore ereditato o iniziale, a seconda della proprietà. |
Proprietà correlate
will-change è un suggerimento per le prestazioni relativo alle proprietà che si animano effettivamente. Si abbina naturalmente con:
transform— il target più comune diwill-change, poiché i transform sono ottimizzati dalla GPU.opacity— anch'essa gestita in compositing e target frequente per le dissolvenze.transitioneanimation— i meccanismi che guidano i cambiamenti su cui si sta suggerendo.z-index— rilevante perché alcuni valori diwill-changecreano un nuovo contesto di sovrapposizione.