Saiba como evitar mudanças repentinas de layout para melhorar a experiência do usuário
Publicado em: 5 de maio de 2020. Última atualização: 7 de fevereiro de 2025
A Cumulative Layout Shift (CLS) é uma das três métricas das Core Web Vitals. Ela mede a instabilidade do conteúdo combinando o quanto do conteúdo visível mudou na janela de visualização com a distância que os elementos afetados percorreram.
As mudanças de layout podem distrair os usuários. Imagine que você começou a ler um artigo quando, de repente, os elementos mudam de lugar na página, fazendo com que você se perca e precise encontrar seu lugar novamente. Isso é muito comum na Web, inclusive ao ler notícias ou tentar clicar nos botões "Pesquisar" ou "Adicionar ao carrinho". Essas experiências são visualmente desagradáveis e frustrantes. Elas geralmente são causadas quando elementos visíveis são forçados a se mover porque outro elemento foi adicionado ou redimensionado repentinamente na página.
Para oferecer uma boa experiência ao usuário, os sites devem ter um CLS de 0,1 ou menos em pelo menos 75% das visitas à página.
Ao contrário das outras métricas principais, que são valores baseados em tempo medidos em segundos ou milissegundos, a pontuação de CLS é um valor sem unidade baseado em um cálculo de quanto conteúdo está mudando e em que medida.
Neste guia, vamos abordar a otimização de causas comuns de mudanças de layout.
As causas mais comuns de um CLS ruim são:
- Imagens sem dimensões.
- Anúncios, incorporações e iframes sem dimensões.
- Conteúdo injetado dinamicamente, como anúncios, incorporações e iframes sem dimensões.
- Fontes da Web.
Entender as causas das mudanças de layout
Antes de procurar soluções para problemas comuns de CLS, é importante entender sua pontuação de CLS e de onde vêm as mudanças.
CLS em ferramentas de laboratório x campo
É comum ouvir desenvolvedores acharem que o CLS medido pelo Relatório de experiência do usuário do Chrome (CrUX) está incorreto porque não corresponde ao CLS medido com o Chrome DevTools ou outras ferramentas de laboratório. As ferramentas de laboratório de desempenho da Web, como o Lighthouse, podem não mostrar o CLS completo de uma página, já que normalmente fazem um carregamento básico para medir algumas métricas de desempenho da Web e fornecer orientações. No entanto, os fluxos de usuários do Lighthouse permitem medir além da auditoria de carregamento de página padrão.
O CrUX é o conjunto de dados do Google do programa Métricas da Web. Por isso, o CLS é medido durante toda a vida útil da página, e não apenas durante o carregamento inicial, que é o que as ferramentas de laboratório normalmente medem.
As mudanças de layout são muito comuns durante o carregamento da página, já que todos os recursos necessários são buscados para renderizar a página inicialmente, mas elas também podem acontecer após o carregamento inicial. Muitas mudanças pós-carregamento podem ocorrer como resultado de uma interação do usuário e, portanto, serão excluídas da pontuação de CLS, já que são mudanças esperadas, desde que ocorram em até 500 milissegundos dessa interação.
No entanto, outras mudanças inesperadas para o usuário podem ser incluídas quando não há uma interação qualificada. Por exemplo, se você rolar mais pela página e o conteúdo carregado de forma lenta for carregado, isso vai causar mudanças. Outras causas comuns de CLS pós-carregamento são interações de transições, por exemplo, em aplicativos de página única, que levam mais tempo do que o período de carência de 500 milissegundos.
O PageSpeed Insights mostra o CLS percebido pelo usuário de um URL na seção "Descubra o que seus usuários reais estão enfrentando" e o CLS de carregamento com base em laboratório na seção "Diagnosticar problemas de desempenho". As diferenças entre esses valores provavelmente são resultado do CLS pós-carregamento.
Identificar problemas de CLS de carregamento
Quando as pontuações de CLS do CrUX e do Lighthouse no PageSpeed Insights estão amplamente alinhadas, isso geralmente indica que há um problema de CLS de carregamento detectado pelo Lighthouse. Nesse caso, o Lighthouse vai ajudar com duas auditorias para fornecer mais informações sobre imagens que causam CLS devido à falta de largura e altura, além de listar todos os elementos que mudaram no carregamento da página e a contribuição deles para a CLS. Para ver essas auditorias, filtre por auditorias de CLS:
O painel de desempenho no DevTools oferece muitas informações sobre mudanças de layout:
Layout Shift. Ao clicar nos diamantes, uma animação do turno e os detalhes aparecem no painel Resumo.
As trocas de layout são destacadas na faixa Trocas de layout. A linha roxa agrupa turnos em clusters, e os diamantes mostram turnos individuais nesse cluster. O tamanho do diamante é proporcional ao tamanho da mudança, permitindo que você se concentre nas maiores mudanças.
Ao clicar em uma mudança, um pop-up aparece com uma animação da mudança e destaca os elementos em roxo.
Além disso, a visualização Resumo de um registro Layout Shift inclui o horário de início, a pontuação de mudança e os elementos alterados. Isso é especialmente útil para ter mais detalhes sobre problemas de CLS de carregamento, já que eles são facilmente replicados com um perfil de performance de recarga.
Isso também se vincula ao insight Causadores da mudança de layout mostrado no painel Insights à esquerda, que mostra o CLS total na parte de cima, além de possíveis motivos para mudanças de layout.
Identificar problemas de CLS após o carregamento
A discordância entre as pontuações de CLS do CrUX e do Lighthouse geralmente indica CLS pós-carregamento. Essas mudanças podem ser difíceis de rastrear sem dados de campo. Para informações sobre como coletar dados de campo, consulte Medir elementos CLS no campo.
A visualização de métricas em tempo real do painel de desempenho permite interagir com a página e monitorar a pontuação de CLS para identificar interações que causam grandes mudanças de layout.
Como alternativa ao uso das DevTools, você pode navegar na sua página da Web enquanto grava mudanças de layout usando um Performance Observer colado no console.
Depois de configurar o monitoramento de turnos, tente replicar problemas de CLS pós-carga. A CLS geralmente acontece enquanto o usuário rola uma página, quando o conteúdo carregado de forma lenta é carregado completamente sem espaço reservado para ele. A mudança de conteúdo quando o usuário mantém o ponteiro sobre ele é outra causa comum de CLS pós-carregamento. Qualquer mudança de conteúdo durante uma dessas interações é considerada inesperada, mesmo que aconteça em menos de 500 milissegundos.
Para mais informações, consulte Depurar mudanças de layout.
Depois de identificar as causas comuns de CLS, o modo de fluxo do usuário de intervalos de tempo do Lighthouse também pode ser usado para garantir que os fluxos de usuários típicos não regridam com a introdução de mudanças de layout.
Medir elementos de CLS no campo
Monitorar a CLS no campo pode ser muito útil para determinar em quais circunstâncias ela ocorre e reduzir as possíveis causas. Como a maioria das ferramentas de laboratório, as de campo medem apenas os elementos que mudaram, mas isso geralmente fornece informações suficientes para identificar a causa. Também é possível usar as medições de campo do CLS para determinar quais problemas têm a maior prioridade de correção.
A biblioteca web-vitals tem funções de atribuição que permitem coletar essas informações adicionais. Para mais informações, consulte Depurar o desempenho no campo. Outros provedores de RUM também começaram a coletar e apresentar esses dados de maneira semelhante.
Causas comuns de CLS
Depois de identificar as causas do CLS, comece a corrigir os problemas. Nesta seção, vamos mostrar alguns dos motivos mais comuns para o CLS e o que você pode fazer para evitá-los.
Imagens sem dimensões
Sempre inclua atributos de tamanho width e height nas imagens e nos elementos de vídeo. Como alternativa, reserve o espaço necessário com CSS aspect-ratio ou similar. Essa abordagem garante que o navegador possa alocar a quantidade correta de espaço no documento enquanto a imagem está sendo carregada.
Histórico dos atributos width e height em imagens
Nos primeiros dias da Web, os desenvolvedores adicionavam atributos width e height às tags <img> para garantir que espaço suficiente fosse alocado na página antes que o navegador começasse a buscar imagens. Isso minimiza o reflow e o novo layout.
<img src="puppy.jpg" width="640" height="360" alt="Puppy with balloons">
width e height neste exemplo não incluem unidades. Essas dimensões de "pixel" garantem que o navegador reserve uma área de 640 x 360 no layout da página. A imagem seria esticada para se ajustar a esse espaço, independentemente de as dimensões reais corresponderem a ele.
Quando o Web design responsivo foi lançado, os desenvolvedores começaram a omitir width e height e passaram a usar CSS para redimensionar imagens:
img {
width: 100%; /* or max-width: 100%; */
height: auto;
}
No entanto, como o tamanho da imagem não é especificado, o espaço não pode ser alocado até que o navegador comece a fazer o download e determine as dimensões. À medida que as imagens são carregadas, o texto muda para baixo na página para abrir espaço, criando uma experiência confusa e frustrante para o usuário.
É aí que entra a proporção. A proporção de uma imagem é a relação entre a largura e a altura dela. É comum ver isso expresso como dois números separados por dois pontos (por exemplo, 16:9 ou 4:3). Para uma proporção x:y, a imagem tem x unidades de largura e y unidades de altura.
Isso significa que, se soubermos uma das dimensões, a outra poderá ser determinada. Para uma proporção de 16:9:
- Se puppy.jpg tiver uma altura de 360 px, a largura será 360 x (16 / 9) = 640 px.
- Se puppy.jpg tiver uma largura de 640 px, a altura será 640 x (9 / 16) = 360 px.
Conhecer a proporção de uma imagem permite que o navegador calcule e reserve espaço suficiente para a altura e a área associada.
Prática recomendada moderna para definir dimensões de imagem
Como os navegadores modernos definem a proporção padrão das imagens com base nos atributos width e height de uma imagem, é possível evitar mudanças de layout definindo esses atributos na imagem e incluindo o CSS anterior na sua folha de estilo.
<!-- set a 640:360 i.e a 16:9 aspect ratio -->
<img src="puppy.jpg" width="640" height="360" alt="Puppy with balloons">
Todos os navegadores vão adicionar uma proporção padrão com base nos atributos width e height do elemento.
Isso calcula uma proporção com base nos atributos width e height antes do carregamento da imagem. Ele fornece essas informações no início do cálculo do layout. Assim que uma imagem é definida como tendo uma determinada largura (por exemplo, width: 100%), a proporção é usada para calcular a altura.
Esse valor aspect-ratio é calculado pelos principais navegadores à medida que o HTML é processado, em vez de uma folha de estilo do user agent padrão. Leia esta postagem para saber mais sobre o assunto. Por isso, o valor é mostrado de maneira um pouco diferente. Por exemplo, o Chrome mostra assim na seção "Estilos" do painel "Elemento":
img[Attributes Style] {
aspect-ratio: auto 640 / 360;
}
O Safari se comporta de maneira semelhante, usando uma fonte de estilo Atributos HTML. O Firefox não mostra esse aspect-ratio calculado no painel Inspector, mas o usa para o layout.
A parte auto do código anterior é importante porque faz com que as dimensões da imagem substituam a proporção padrão depois que a imagem é baixada. Se as dimensões da imagem forem diferentes, isso ainda vai causar alguma mudança de layout depois que a imagem for carregada, mas garante que a proporção da imagem ainda seja usada quando ela estiver disponível, caso o HTML esteja incorreto. Mesmo que a proporção real seja diferente da padrão, ela ainda causa menos mudança de layout do que o tamanho padrão 0x0 de uma imagem sem dimensões fornecidas.
Para uma análise detalhada sobre proporção e mais informações sobre imagens responsivas, consulte Carregamento de página sem falhas com proporções de mídia.
Se a imagem estiver em um contêiner, use CSS para redimensioná-la de acordo com a largura do contêiner. Definimos height: auto; para evitar o uso de um valor fixo para a altura da imagem.
img {
height: auto;
width: 100%;
}
E as imagens responsivas?
Ao trabalhar com imagens responsivas, srcset define as imagens que você permite que o navegador selecione e o tamanho de cada uma delas. Para garantir que os atributos de largura e altura <img> possam ser definidos, cada imagem precisa usar a mesma proporção.
<img
width="1000"
height="1000"
src="puppy-1000.jpg"
srcset="puppy-1000.jpg 1000w, puppy-2000.jpg 2000w, puppy-3000.jpg 3000w"
alt="Puppy with balloons"
/>
As proporções das imagens também podem mudar dependendo da direção de arte. Por exemplo, você pode incluir uma foto cortada de uma imagem para janelas de visualização estreitas e mostrar a imagem completa em computadores desktop:
<picture>
<source media="(max-width: 799px)" srcset="puppy-480w-cropped.jpg" />
<source media="(min-width: 800px)" srcset="puppy-800w.jpg" />
<img src="puppy-800w.jpg" alt="Puppy with balloons" />
</picture>
O Chrome, o Firefox e o Safari agora oferecem suporte à definição de width e height nos elementos
<source> em um determinado elemento <picture>:
<picture>
<source media="(max-width: 799px)" srcset="puppy-480w-cropped.jpg" width="480" height="400" />
<source media="(min-width: 800px)" srcset="puppy-800w.jpg" width="800" height="400" />
<img src="puppy-800w.jpg" alt="Puppy with balloons" width="800" height="400" />
</picture>
Anúncios, incorporações e outros conteúdos carregados posteriormente
As imagens não são o único tipo de conteúdo que pode causar mudanças de layout. Anúncios, incorporações, iframes e outros conteúdos injetados dinamicamente podem fazer com que o conteúdo que aparece depois deles seja movido para baixo, aumentando o CLS.
Os anúncios são um dos maiores contribuintes para as mudanças de layout na Web. As redes de publicidade e os publishers geralmente aceitam tamanhos de anúncios dinâmicos. Os tamanhos de anúncio aumentam a performance e a receita devido a taxas de cliques mais altas e mais anúncios competindo no leilão. Infelizmente, isso pode prejudicar a experiência do usuário, já que os anúncios empurram para baixo o conteúdo visível que você está vendo na página.
Com os widgets incorporáveis, você pode incluir conteúdo da Web portátil na sua página, como vídeos do YouTube, mapas do Google Maps e postagens de redes sociais. No entanto, esses widgets geralmente não sabem o tamanho do conteúdo antes de serem carregados. Como resultado, as plataformas que oferecem incorporações nem sempre reservam espaço para os widgets, o que causa mudanças de layout quando eles finalmente são carregados.
As técnicas para lidar com eles são semelhantes. As principais diferenças são o nível de controle que você tem sobre o conteúdo a ser inserido. Se ele for inserido por terceiros, como um parceiro de publicidade, talvez você não saiba o tamanho exato do conteúdo que será inserido nem consiga controlar as mudanças de layout que ocorrem nesses incorporados.
Reservar espaço para conteúdo carregado posteriormente
Ao colocar conteúdo de carregamento atrasado no fluxo de conteúdo, é possível evitar mudanças de layout reservando o espaço para eles no layout inicial.
Uma abordagem é adicionar uma regra CSS min-height para reservar espaço ou, para conteúdo responsivo, como anúncios, usar a propriedade CSS aspect-ratio de maneira semelhante à forma como os navegadores a usam automaticamente para imagens com dimensões fornecidas.
Talvez seja necessário considerar diferenças sutis nos tamanhos de anúncios ou marcadores de posição em vários formatos usando consultas de mídia.
Para conteúdo que não tem uma altura fixa, como anúncios, talvez não seja possível reservar a quantidade exata de espaço necessária para eliminar totalmente a mudança de layout. Se um anúncio menor for veiculado, um editor poderá estilizar um contêiner maior para evitar mudanças de layout ou escolher o tamanho mais provável para o slot de anúncio com base em dados históricos. A desvantagem dessa abordagem é que ela aumenta a quantidade de espaço em branco na página.
Em vez disso, defina o tamanho inicial como o menor que será usado e aceite algum nível de mudança para conteúdo maior. Usar min-height, como sugerido anteriormente, permite que o elemento pai cresça conforme necessário, reduzindo o impacto das mudanças de layout em comparação com o tamanho padrão de 0 px de um elemento vazio.
Evite recolher o espaço reservado mostrando um marcador de posição se, por exemplo, nenhum anúncio for retornado. Remover o espaço reservado para elementos pode causar tanto CLS quanto inserir conteúdo.
Coloque o conteúdo de carregamento atrasado mais abaixo na janela de visualização
O conteúdo injetado dinamicamente mais perto da parte de cima da janela de visualização geralmente causa mudanças de layout maiores do que o conteúdo injetado mais abaixo. No entanto, inserir conteúdo em qualquer lugar da janela de visualização ainda causa alguma mudança. Se não for possível reservar espaço para o conteúdo injetado, recomendamos colocá-lo mais tarde na página para reduzir o impacto no CLS.
Evite inserir conteúdo novo sem interação do usuário
Você provavelmente já passou por mudanças de layout devido a uma interface que aparece na parte de cima ou de baixo da janela de visualização ao tentar carregar um site. Assim como os anúncios, isso geralmente acontece com banners e formulários que mudam o restante do conteúdo da página:
Se você precisar mostrar esses tipos de recursos da interface, reserve espaço suficiente no viewport com antecedência (por exemplo, usando um marcador de posição ou uma interface esqueleto) para que, quando ele for carregado, não cause uma mudança inesperada no conteúdo da página. Se preferir, verifique se o elemento não faz parte do fluxo do documento sobrepondo o conteúdo quando isso fizer sentido. Consulte a postagem Práticas recomendadas para avisos de cookies para mais recomendações sobre esses tipos de componentes.
Em alguns casos, adicionar conteúdo dinamicamente é uma parte importante da experiência do usuário. Por exemplo, ao carregar mais produtos em uma lista de itens ou ao atualizar o conteúdo do feed ao vivo. Há várias maneiras de evitar mudanças de layout inesperadas nesses casos:
- Substitua o conteúdo antigo pelo novo em um contêiner de tamanho fixo ou use um carrossel e remova o conteúdo antigo após a transição. Desative todos os links e controles até que a transição seja concluída para evitar cliques ou toques acidentais enquanto o novo conteúdo é carregado.
- Faça com que o usuário inicie o carregamento de novo conteúdo para que ele não seja surpreendido pela mudança (por exemplo, com um botão "Carregar mais" ou "Atualizar"). Recomendamos pré-buscar o conteúdo antes da interação do usuário para que ele apareça imediatamente. Vale lembrar que mudanças de layout que ocorrem em até 500 milissegundos da entrada do usuário não são contabilizadas na CLS.
- Carregue o conteúdo fora da tela e sobreponha um aviso ao usuário de que ele está disponível (por exemplo, com um botão "Rolar para cima").
Animações
As mudanças nos valores das propriedades de CSS podem exigir que o navegador reaja a elas. Alguns valores, como box-shadow e box-sizing, acionam um novo layout, pintura e composição. Mudar as propriedades top e left também causa mudanças de layout, mesmo quando o elemento movido está em uma camada própria. Evite animar usando essas propriedades.
Outras propriedades de CSS podem ser alteradas sem acionar novas disposições. Isso inclui o uso de animações transform para transladar, dimensionar, girar ou distorcer elementos.
Animações combinadas usando translate não podem afetar outros elementos e, portanto, não contam para o CLS. Animações não compostas também não causam readequação do layout. Para saber mais sobre quais propriedades CSS acionam mudanças de layout, consulte Animações de alta performance.
Fontes da Web
O download e a renderização de fontes da Web geralmente são processados de uma das duas maneiras a seguir antes do download da fonte:
- A fonte substituta é trocada pela fonte da Web, causando um instante de texto não estilizado (FOUT).
- O texto "invisível" é mostrado usando a fonte substituta até que uma webfont esteja disponível e o texto fique visível (FOIT, flash de texto invisível).
As duas abordagens podem causar mudanças de layout. Mesmo que o texto esteja invisível, ele ainda é apresentado usando a fonte substituta. Assim, quando a webfont é carregada, o bloco de texto e o conteúdo ao redor mudam da mesma forma que para a fonte visível.
As ferramentas a seguir podem ajudar você a minimizar a mudança de texto:
- O
font-display: optionalpode evitar um novo layout, já que a fonte da Web só é usada se estiver disponível no momento do layout inicial. - Verifique se a fonte substituta adequada está sendo usada. Por exemplo, usar
font-family: "Google Sans", sans-serif;garante que a fonte de substituiçãosans-serifdo navegador seja usada enquanto"Google Sans"é carregado. Não especificar uma fonte substituta usando apenasfont-family: "Google Sans"significa que a fonte padrão será usada, que no Chrome é "Times", uma fonte serifada que é uma correspondência pior do que a fonte padrãosans-serif. - Minimize as diferenças de tamanho entre a fonte substituta e a fonte da Web usando as novas APIs
size-adjust,ascent-override,descent-overrideeline-gap-override, conforme detalhado na postagem Substituições de fontes aprimoradas. - A API Font Loading pode reduzir o tempo necessário para receber as fontes necessárias.
- Carregue fontes da Web essenciais o mais rápido possível usando
<link rel=preload>. Uma fonte pré-carregada tem mais chances de atender à primeira renderização, e não há mudança de layout.
Leia Práticas recomendadas para fontes para conhecer outras práticas recomendadas.
Reduza o CLS garantindo que as páginas estejam qualificadas para o bfcache
Uma técnica altamente eficaz para manter as pontuações de CLS baixas é garantir que suas páginas da Web estejam qualificadas para o cache de volta/avançar (bfcache).
O bfcache mantém as páginas na memória do navegador por um curto período depois que você sai delas. Assim, se você voltar, elas serão restauradas exatamente como você as deixou. Isso significa que a página totalmente carregada fica disponível instantaneamente, sem as mudanças que normalmente são vistas durante o carregamento por qualquer um dos motivos mencionados anteriormente.
Embora isso ainda possa significar que o carregamento inicial da página encontra mudanças de layout, quando um usuário volta pelas páginas, ele não vê as mesmas mudanças de layout repetidamente. Sempre tente evitar essas mudanças, mesmo no carregamento inicial. Mas, quando isso for mais difícil de resolver completamente, pelo menos reduza o impacto evitando-as em qualquer navegação do bfcache.
A navegação para frente e para trás é comum em muitos sites. Por exemplo, voltar para uma página de conteúdo, uma página de categoria ou resultados da pesquisa.
Quando esse recurso foi lançado no Chrome, notamos melhorias significativas no CLS.
O bfcache é usado por padrão em todos os navegadores, mas alguns sites não estão qualificados por vários motivos. Leia o guia do bfcache para mais detalhes sobre como testar e identificar problemas que impedem o uso do bfcache. Assim, você garante o uso total desse recurso para melhorar a pontuação geral de CLS do seu site.
Conclusão
Há várias técnicas para identificar e melhorar a CLS, conforme detalhado anteriormente neste guia. Há tolerâncias integradas às Core Web Vitals. Portanto, mesmo que não seja possível eliminar completamente o CLS, o uso de algumas dessas técnicas pode reduzir o impacto. Isso vai permitir que você fique dentro desses limites, criando uma experiência melhor para os usuários do seu site.