Propriedade CSS will-change
Use a propriedade CSS will-change para indicar como um elemento deve mudar no futuro. Leia sobre a propriedade e experimente os exemplos.
A propriedade will-change fornece ao navegador uma dica sobre como se espera que um elemento mude num futuro próximo, para que ele possa configurar as otimizações necessárias antes de a mudança ocorrer — em vez de tentar otimizar exatamente no quadro em que a alteração começa.
Esta página aborda o que will-change faz, quando (e quando não) utilizá-la, os valores aceites, um exemplo executável e as armadilhas que facilitam o seu uso indevido.
Por que will-change existe
Propriedades como transform e opacity são baratas de animar porque o navegador pode promover o elemento à sua própria camada de composição (uma superfície separada que a GPU pode mover, esmaecer ou dimensionar sem redesenhar o restante da página). No entanto, criar essa camada tem um custo em tempo e memória. Se o navegador só descobre que precisa de uma camada no momento em que a animação começa, o primeiro quadro pode gaguejar.
will-change permite informar o navegador com antecedência quais propriedades estão prestes a mudar, para que ele possa preparar a camada com antecedência e manter a animação fluida desde o primeiro quadro.
Os valores são separados por vírgula. A propriedade will-change aceita estes valores: auto, um <custom-ident> como um nome de propriedade (transform, opacity, scroll-position, …), initial, inherit ou unset.
Esta propriedade deve ser usada com cautela. Diferentes navegadores tratam esta propriedade de forma diferente, e o uso excessivo pode fazer o navegador ignorá-la. O uso excessivo também pode forçar camadas de composição desnecessárias, aumentando o uso de memória e degradando o desempenho.
Uso correto da propriedade will-change
- Não a aplique a demasiados elementos. Cada dica
will-changepode obrigar o navegador a manter uma camada de composição ativa, o que consome memória. Indicar centenas de elementos pode tornar a página mais lenta em vez de acelerá-la. - Adicione e remova-a com script, em torno da alteração. Defina
will-changepouco antes da mudança (por exemplo emmouseenteroufocus), depois remova-a assim que a animação terminar para que o navegador possa libertar a camada. - Não a use como otimização prematura. Se uma página já anima de forma suave, deixe-a como está. Recorra a
will-changeapenas para resolver um problema de desempenho medido — é um último recurso, não um padrão. - Dê tempo ao navegador para se preparar. O objetivo de
will-changeé avisar o navegador antes da mudança. Defini-la no mesmo quadro em que a animação começa derrota o propósito. - Esteja ciente de que pode afetar a renderização. Valores que criam um contexto de empilhamento (como
will-change: opacityouwill-change: transform) podem alterar a forma como o elemento se sobrepõe aos seus irmãos, tal como a aplicação efetiva dessas propriedades faria.
| Valor Inicial | auto |
|---|---|
| Aplica-se a | Todos os elementos. |
| Herdado | Não. |
| Animável | Não. |
| Versão | CSS Transitions Module Level 1 |
| Sintaxe DOM | object.style.willChange = "transform"; |
Nota: em JavaScript, o nome da propriedade usa camelCase (willChange), enquanto a propriedade CSS usa hífens (will-change).
Sintaxe
Valores CSS will-change
will-change: auto | <custom-ident> | initial | inherit | unset;Exemplo da propriedade will-change:
Exemplo de código 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>Definir e limpar will-change com script
O padrão recomendado é adicionar a dica pouco antes de uma interação e removê-la depois, para que o navegador mantenha a camada apenas enquanto for necessário:
.card {
transition: transform 0.3s;
}
/* Hint the browser only while the user hovers. */
.card:hover {
will-change: transform;
transform: scale(1.05);
}Para animações de maior duração ou controladas por JavaScript, ative e desative-a no código:
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";
});Valores
| Valor | Descrição |
|---|---|
| auto | A otimização padrão do navegador deve ser aplicada. |
<custom-ident> | Especifica a propriedade CSS que se espera que mude ou anime no elemento num futuro próximo. Se a propriedade for uma abreviação, as alterações serão expandidas para todas as suas propriedades longas. |
| initial | Faz a propriedade usar o seu valor padrão. |
| inherit | Herda a propriedade do seu elemento pai. |
| unset | Redefine a propriedade para o seu valor herdado ou valor inicial, dependendo da propriedade. |
Propriedades relacionadas
will-change é uma dica de desempenho para as propriedades que você realmente anima. Ela combina naturalmente com:
transform— o alvo mais comum dewill-change, pois as transformações são amigáveis à GPU.opacity— também composta e um alvo frequente para efeitos de esmaecimento.transitioneanimation— os mecanismos que conduzem as alterações sobre as quais você está dando a dica.z-index— relevante porque alguns valores dewill-changecriam um novo contexto de empilhamento.