A versão curta
- Um gradiente CSS estático custa quase nada a carregar, porque é uma linha de texto e não um ficheiro para descarregar e descodificar.
- Os gradientes custam tempo de pintura, que cresce com a área pintada e o número de camadas, mas um gradiente estático é pintado uma vez e depois reutilizado.
- Os riscos reais de desempenho são os filtros de desfocado grandes, os fundos que se repintam ao deslocar e as animações de gradiente que repintam a cada fotograma.
- Animar o transform ou a opacity numa camada de gradiente costuma ser muito mais barato do que animar o background-position ou as paragens de cor.
- A única resposta fiável para uma página concreta é medi-la, com o paint flashing e uma gravação de Performance nas ferramentas de programador do navegador.
Nesta página
Um bom desempenho dos gradientes CSS é o caso normal: um gradiente estático não abranda um site de forma que se note. É uma linha de texto, por isso não há nada para descarregar, nada para descodificar e nada por que esperar. Os gradientes custam um pouco de tempo de pintura, como qualquer outra cor da página. As páginas lentas vêm de alguns padrões específicos construídos sobre gradientes: desfocados grandes, repinturas ao deslocar e animações que repintam a cada fotograma. Este guia mostra qual é qual e como verificar a tua própria página.
Carregamento: gradientes contra imagens
background: linear-gradient(135deg, #1e1b4b, #7c3aed 55%, #f472b6); tem 67 carateres. Chega dentro da tua folha de estilos, não precisa de um pedido extra e desenha-se nítido em qualquer tamanho e densidade de píxeis. Um fundo em imagem precisa do seu próprio pedido, tem de ser descodificado antes de poder ser desenhado e tem de ser grande o suficiente para ecrãs grandes e de alta densidade.
linear-gradient(135deg, #1e1b4b, #7c3aed 55%, #f472b6)| Fundo | Descarga | Memória descodificada a 1920×1080 |
|---|---|---|
| Gradiente CSS | Algumas dezenas de bytes no teu CSS | Sem bitmap para guardar; pintado conforme necessário |
| Imagem comprimida (AVIF, WebP, JPEG) | Um ficheiro à parte, muitas vezes de dezenas a centenas de quilobytes | Cerca de 8,3 MB (largura × altura × 4 bytes) |
| A mesma imagem a 3840×2160 para 4K nítido | Ainda maior | Cerca de 33 MB |
Portanto, para fundos simples e moderadamente sobrepostos, o CSS ganha sempre no carregamento. As imagens continuam a fazer sentido quando o fundo é genuinamente complexo, como um gradiente de malha pictórico com muitos pontos de cor ou uma textura fotográfica. Nesse caso, a troca é peso do ficheiro por riqueza visual, e muitas vezes compensa.
Pintura: o que custa um gradiente no ecrã
Para mostrar um gradiente, o navegador calcula uma cor para cada píxel que cobre: isso é pintar. O trabalho cresce com a área pintada, o número de camadas de gradiente empilhadas e quaisquer efeitos por cima. Para um fundo estático acontece uma vez, e o resultado é reutilizado enquanto te deslocas ou interages, a não ser que algo o invalide.
Pintado uma vez
- Um gradiente estático num cartão ou herói
- Vários brilhos radiais sobrepostos que não se movem
- Uma textura de ruído em mosaico sobre um gradiente
- Uma borda com gradiente desenhada com fundos
Pintado vezes sem conta
- Animar o
background-positionou as paragens de cor background-attachment: fixedao deslocar- Desfocado com
backdrop-filtersobre conteúdo em movimento - Um elemento com gradiente que muda continuamente de tamanho
Os riscos reais: desfocado, fundos fixos e animação
Desfocados grandes. O filter: blur() e o backdrop-filter recolhem muitos píxeis vizinhos para cada píxel, e o trabalho cresce tanto com o raio do desfocado como com a área. Um gradiente desfocado pintado uma vez costuma estar bem. Um backdrop-filter sobre conteúdo que se desloca por baixo tem de ser recalculado à medida que esse conteúdo se move, e é aí que as interfaces de glassmorphism tendem a engasgar em telemóveis modestos.
Fundos fixos. O background-attachment: fixed mantém um fundo parado enquanto a página se desloca, o que pode obrigá-lo a repintar a cada passo de deslocação. Se queres um gradiente que fique no sítio, um elemento com position: fixed por trás do conteúdo costuma ser mais barato, porque o navegador o pode mover como uma camada à parte.
Animação. Mover o background-position ou animar paragens de cor com @property repinta o elemento a cada fotograma. Num botão isso é trivial. Num herói de ecrã inteiro, é trabalho contínuo enquanto a página estiver aberta, o que se nota em calor e desgaste da bateria nos telemóveis.
/* repaints the whole hero every frame */
.hero--costly {
background: linear-gradient(120deg, #1e1b4b, #7c3aed, #f472b6);
background-size: 300% 300%;
animation: pan 12s ease-in-out infinite alternate;
}
/* the browser can usually just move a finished layer */
.hero--cheap::before {
content: "";
position: absolute;
inset: -50%;
z-index: -1;
background: conic-gradient(#1e1b4b, #7c3aed, #f472b6, #1e1b4b);
animation: turn 40s linear infinite;
}
@keyframes pan { to { background-position: 100% 50%; } }
@keyframes turn { to { transform: rotate(1turn); } }transform, que os navegadores costumam conseguir tratar no compositor sem repintar.O guia sobre o gradiente animado em CSS tem o conjunto completo de técnicas, das mais baratas às mais flexíveis.
Camadas e will-change
Promover um elemento à sua própria camada do compositor, com will-change: transform ou uma animação de transform ativa, é o que torna possível uma animação barata. Não é gratuito: cada camada guarda o seu próprio bitmap na memória gráfica, aproximadamente largura × altura × 4 bytes em píxeis do dispositivo. Uma camada sobredimensionada para o fundo de um herói está bem. Dezenas de cartões promovidos, cada um com a sua camada de gradiente, podem gastar mais memória do que poupam em tempo de pintura. Acrescenta will-change aos elementos que realmente animam, não como regra geral.
| Padrão | Trabalho do navegador | Alternativa mais barata |
|---|---|---|
background-position animado num herói | Repintar a cada fotograma | transform numa camada de gradiente sobredimensionada |
background-attachment: fixed | Repintar ao deslocar | Uma camada de gradiente com position: fixed por trás do conteúdo |
backdrop-filter sobre conteúdo que se desloca | Desfocado recalculado à medida que o conteúdo se move | Uma camada estática pré-desfocada, ou uma área desfocada mais pequena |
| Filtro de ruído SVG ao vivo num elemento grande | O filtro corre sobre cada píxel repintado | Uma pequena imagem de ruído em mosaico |
will-change em todos os cartões | Muitas camadas guardadas na memória gráfica | will-change só no que anima |
Como medir o desempenho dos gradientes
- 1
Ativa o paint flashing
Nas DevTools do Chrome, abre o painel Rendering e ativa o Paint flashing. Tudo o que pisca a verde quando nada devia estar a mudar está a ser repintado.
- 2
Grava um traço de Performance
Grava alguns segundos de deslocação ou de animação parada no painel Performance. Vê quanto de cada fotograma se gasta em pintura e se há fotogramas perdidos.
- 3
Limita o CPU
Usa a limitação de CPU do painel Performance para simular um dispositivo mais lento. Um herói que corre suave num portátil rápido pode ter dificuldades num telemóvel de gama média.
- 4
Vê o painel Layers
Vê quantas camadas de compositor existem e quanta memória usam. Um número inesperadamente alto de camadas costuma significar que o
will-changeé usado em excesso. - 5
Testa o dispositivo real
Termina num telemóvel a sério. O calor e o desgaste da bateria de uma animação constante passam facilmente despercebidos num computador.
O guia da web.dev sobre desempenho de renderização explica o pipeline por trás destas ferramentas: estilo, layout, pintura e composição. Saber que fase o teu gradiente desencadeia diz-te se é barato.
Uma lista de verificação de desempenho para gradientes
- Usa gradientes CSS para fundos simples e sobrepostos; imagens só quando o visual realmente as exige.
- Mantém os raios de desfocado modestos e evita o
backdrop-filtersobre áreas grandes que se deslocam. - Substitui o
background-attachment: fixedpor uma camada de posição fixa. - Anima o
transformou aopacity, não obackground-position, em áreas grandes. - As animações lentas e ambiente podem parar por completo para quem usa movimento reduzido.
- Acrescenta grão como uma pequena imagem em mosaico, não como um filtro SVG ao vivo num elemento grande; vê a textura de ruído em CSS.
- Mede antes e depois com o paint flashing e uma gravação de Performance.
Perguntas frequentes
Os gradientes CSS abrandam um site?
Os gradientes CSS estáticos não o fazem de forma que se note. Não precisam de descarga e são pintados uma vez. Os desfocados grandes, os fundos fixos e a animação constante é que custam desempenho.
Um gradiente CSS é mais rápido do que uma imagem de fundo?
Normalmente sim. Um gradiente são algumas dezenas de bytes de CSS sem pedido nem descodificação, enquanto uma imagem precisa de uma descarga e fica na memória como um bitmap completo.
Os gradientes animados são maus para o desempenho?
Animar o background-position ou as paragens de cor repinta a cada fotograma, o que importa em áreas grandes. Animar o transform ou a opacity numa camada de gradiente costuma ser muito mais barato.
Porque é lento o meu fundo em gradiente desfocado?
O desfocado recolhe muitos píxeis vizinhos para cada píxel, por isso o custo cresce com o raio e a área. É pior com backdrop-filter sobre conteúdo que se desloca ou anima.
Como verifico se o meu gradiente está a ser repintado?
Ativa o Paint flashing no painel Rendering das DevTools do Chrome. As áreas que continuam a piscar com a página parada estão a ser repintadas.
Escrito pela Gradiently
A equipa por trás da Gradiently, uma ferramenta de design construída em torno dos Marks: gradientes vivos que fazem tudo o que crias parecer teu.
Ver o nosso perfil


