# Desempenho dos gradientes CSS: os gradientes abrandam um site?

[Canonical HTML page](https://gradiently.design/pt-pt/guide/css-gradient-performance)

Um gradiente CSS estático é quase gratuito. Os custos vêm do que as pessoas fazem com os gradientes: desfocados enormes, fundos que se repintam ao deslocar e animações que nunca páram. Eis como distinguir.

## The short version

- 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.

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.

67 carateres de CSS: `linear-gradient(135deg, #1e1b4b, #7c3aed 55%, #f472b6)`

Este fundo inteiro, em qualquer tamanho, custa menos do que uma frase de texto a carregar.

| 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 |

As imagens descodificadas são guardadas como bitmaps completos, seja qual for o tamanho do ficheiro. Os valores de memória são aritmética simples: píxeis vezes quatro bytes.

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](https://gradiently.design/pt-pt/guide/css-mesh-gradient) 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-position` ou as paragens de cor
- `background-attachment: fixed` ao deslocar
- Desfocado com `backdrop-filter` sobre 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](https://gradiently.design/pt-pt/guide/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.

```css
/* 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); } }
```

Dois heróis animados. O segundo anima o `transform`, que os navegadores costumam conseguir tratar no compositor sem repintar.

O guia sobre o [gradiente animado em CSS](https://gradiently.design/pt-pt/guide/css-animated-gradient) 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 |

Padrões comuns de gradiente, o que fazem o navegador fazer e a forma mais leve de obter o mesmo aspeto.

## 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](https://web.dev/articles/rendering-performance) 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-filter` sobre áreas grandes que se deslocam.
- Substitui o `background-attachment: fixed` por uma camada de posição fixa.
- Anima o `transform` ou a `opacity`, não o `background-position`, em áreas grandes.
- As animações lentas e ambiente podem parar por completo para quem usa [movimento reduzido](https://gradiently.design/pt-pt/guide/reduced-motion).
- 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](https://gradiently.design/pt-pt/guide/css-noise-texture).
- Mede antes e depois com o paint flashing e uma gravação de Performance.

## FAQ

### 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.
