Otimizar a Mudança de layout cumulativa

Saiba como evitar mudanças repentinas de layout para melhorar a experiência do usuário

A Mudança de layout cumulativa (CLS) é uma das três métricas Core Web Vitals. Ela mede a instabilidade do conteúdo combinando a quantidade de conteúdo visível que foi movida na janela de visualização com a distância que os elementos afetados se moveram.

Mudanças de layout podem distrair os usuários. Imagine que você começou a ler um artigo quando, de repente, elementos mudam pela página, fazendo você jogar fora e exigindo que encontre o local novamente. Isso é muito comum na Web, inclusive ao ler as notícias ou tentar clicar nos botões "Pesquisar" ou "Adicionar ao carrinho". Essas experiências são visualmente desagradáveis e frustrantes. Eles geralmente ocorrem quando elementos visíveis são forçados a se mover porque outro elemento foi adicionado à página ou redimensionado de repente.

Para oferecer uma boa experiência do usuário, os sites precisam ter uma CLS de 0,1 ou menos em pelo menos 75% das visitas à página.

Os valores bons de CLS estão abaixo de 0,1, os valores ruins são maiores do que 0,25 e qualquer valor entre eles precisa ser melhorado
Valores bons de CLS são 0,1 ou menos. Valores ruins são maiores que 0,25.

Ao contrário das outras Core Web Vitals, 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á sendo deslocado e em que momento.

Neste guia, vamos abordar a otimização das causas comuns de mudanças de layout.

As causas mais comuns de uma 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 começar a procurar soluções para problemas comuns de CLS, é importante entender sua pontuação e a origem das mudanças.

CLS em ferramentas de laboratório versus campo

É comum ouvir os desenvolvedores pensarem que a CLS medida pelo Chrome UX Report (CrUX) está incorreta, porque ela não corresponde à CLS medida usando o Chrome DevTools ou outras ferramentas de laboratório. As ferramentas do Laboratório de desempenho na Web, como o Lighthouse, podem não mostrar a CLS completa de uma página, já que normalmente carregam a página para medir algumas métricas de desempenho da Web e fornecem orientações. No entanto, os fluxos de usuários do Lighthouse permitem fazer medições além da auditoria de carregamento de página padrão.

O CrUX é o conjunto de dados oficial do programa Web Vitals. Para isso, a CLS é medida durante toda a vida da página, e não apenas no carregamento inicial da página que as ferramentas do laboratório costumam medir.

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 inicialmente a página. No entanto, 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 dentro de 500 milissegundos dessa interação.

No entanto, outras mudanças pós-carregamento inesperadas pelo usuário podem ser incluídas quando não houver interação qualificada. Por exemplo, se você rolar mais na página e o conteúdo de carregamento lento for carregado, causando mudanças. Outras causas comuns de CLS pós-carregamento são interações de transições, por exemplo, em apps de página única, que levam mais do que o período de carência de 500 milissegundos.

O PageSpeed Insights mostra a CLS percebida pelo usuário de um URL na seção "Descubra o que seus usuários reais estão enfrentando" e a CLS de carregamento baseada em laboratório na seção "Diagnosticar problemas de desempenho". As diferenças entre esses valores são provavelmente resultado da CLS pós-carregamento.

Captura de tela do PageSpeed Insights que mostra dados no nível do URL destacando a CLS do usuário real, que é consideravelmente maior do que a CLS do Lighthouse
Neste exemplo, o CrUX mede uma CLS muito maior que o Lighthouse.

Identificar problemas de CLS de carga

Quando as pontuações de CLS do CrUX e do Lighthouse do PageSpeed Insights estão amplamente alinhadas, isso geralmente indica que um problema de CLS de carregamento foi detectado pelo Lighthouse. Nesse caso, o Lighthouse vai ajudar com duas auditorias para fornecer mais informações sobre imagens que causam CLS devido à ausência de largura e altura, além de listar todos os elementos que mudaram no carregamento de página e a contribuição de CLS deles. É possível consultar essas auditorias filtrando as auditorias de CLS:

Captura de tela do Lighthouse mostrando as auditorias de CLS com mais informações para ajudar você a identificar e resolver problemas de CLS
Diagnósticos de CLS detalhados do Lighthouse.

O painel Performance no DevTools também destaca as mudanças de layout na seção Experiência. A visualização Resumo de um registro Layout Shift inclui a pontuação cumulativa de mudança de layout, bem como uma sobreposição retangular mostrando as regiões afetadas. Isso é particularmente útil para ter mais detalhes sobre problemas de CLS de carga, já que isso é facilmente replicado com um perfil de desempenho de recarga.

Registros da mudança de layout sendo exibidos no painel de desempenho do Chrome DevTools ao expandir a seção "Experiência"
Depois de registrar um novo rastro no painel "Desempenho", a seção Experiência dos resultados será preenchida com uma barra vermelha que exibe um registro Layout Shift. Ao clicar na gravação, você pode detalhar os elementos afetados mostrando detalhes como as entradas "movido de" e "movido para" nesta imagem.

Identificar problemas de CLS pós-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 a coleta de dados de campo, consulte Medir elementos de CLS no campo.

A extensão Métricas da Web do Chrome pode ser usada para monitorar a CLS enquanto você interage com uma página, seja em uma tela de aviso ou no console, onde é possível acessar mais detalhes sobre os elementos alterados.

Em vez de usar a extensão, você pode navegar na sua página da Web enquanto grava as mudanças de layout usando um Observador de desempenho colado no console.

Depois de configurar o monitoramento de turnos, tente replicar problemas de CLS pós-carregamento. A CLS geralmente acontece enquanto o usuário rola uma página, quando o conteúdo de carregamento lento é totalmente carregado 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 no conteúdo durante qualquer uma dessas interações conta como inesperada, mesmo que ocorra dentro de 500 milissegundos.

Para saber mais, consulte Depurar mudanças de layout.

Depois de identificar quaisquer causas comuns de CLS, o modo de fluxo do usuário de períodos de tempo do Lighthouse também pode ser usado para garantir que os fluxos típicos de usuários não regressem ao introduzir mudanças de layout.

Medir os elementos de CLS no campo

Monitorar a CLS em campo pode ser inestimável para determinar em quais circunstâncias a CLS acontece e restringir as possíveis causas. Como a maioria das ferramentas de laboratório, as de campo medem apenas os elementos que mudaram, mas geralmente fornecem informações suficientes para identificar a causa. Também é possível usar as medições de campo da CLS para determinar quais problemas têm prioridade mais alta a serem corrigidos.

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 da CLS, você pode começar a trabalhar para corrigir os problemas. Nesta seção, vamos mostrar alguns dos motivos mais comuns para a CLS e o que você pode fazer para evitá-los.

Imagens sem dimensões

Sempre inclua os atributos de tamanho width e height nos elementos de imagem e vídeo. Se preferir, reserve o espaço necessário com CSS aspect-ratio ou semelhante. Com essa abordagem, o navegador pode alocar a quantidade correta de espaço no documento enquanto a imagem está carregando.

Imagens sem largura e altura especificadas.
Imagens com largura e altura especificadas.
Relatório do Lighthouse mostrando o impacto de antes/depois na Mudança de layout cumulativa depois de definir dimensões em imagens
Impacto do Lighthouse 6.0 na definição de dimensões de imagem na CLS.

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 minimizaria 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 em "pixel" asseguram que o navegador reservou uma área de 640 x 360 no layout da página. A imagem seria esticada para caber nesse espaço, independentemente de as dimensões reais corresponderem ou não.

Quando o Web design responsivo foi lançado, os desenvolvedores começaram a omitir width e height e começaram 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, não será possível alocar espaço para ela até que o navegador comece a fazer o download e determine as dimensões dela. À medida que as imagens são carregadas, o texto se desloca para baixo na página para dar espaço a elas, criando uma experiência confusa e frustrante para o usuário.

É aqui que entra a proporção. A proporção de uma imagem é a relação entre a largura e a altura. É 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 filhote.jpg tiver uma altura de 360 px, a largura será 360 x (16 / 9) = 640 px
  • Se filhote.jpg tiver uma largura de 640px, a altura será 640 x (9 / 16) = 360px

Saber 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, é possível evitar mudanças de layout definindo esses atributos na imagem e incluindo o CSS anterior na 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. Ela fornece essas informações logo no início do cálculo do layout. Quando uma imagem é informada para ter 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 usar uma folha de estilo padrão do user agent (consulte esta postagem para saber mais sobre o motivo). Portanto, o valor é exibido de maneira um pouco diferente. Por exemplo, o Chrome o exibe da seguinte forma na seção Estilos do painel Elemento:

img[Attributes Style] {
  aspect-ratio: auto 640 / 360;
}

O Safari se comporta de maneira semelhante, usando uma origem de estilo HTML Attributes. O Firefox não exibe esse aspect-ratio calculado no painel Inspector, mas o usa no layout.

A parte auto do código anterior é importante, porque faz com que as dimensões da imagem substituam a proporção padrão após o download da imagem. Se as dimensões da imagem forem diferentes, isso causará alguma mudança no layout depois que a imagem for carregada, mas garante que a proporção ainda seja usada quando estiver disponível, caso o HTML esteja incorreto. Mesmo que a proporção real seja diferente do padrão, ainda haverá menos mudança de layout do que o tamanho padrão 0 x 0 de uma imagem sem dimensões.

Para uma análise detalhada fantástica sobre proporções com mais reflexão sobre imagens responsivas, consulte Carregamento de página sem instabilidade com proporções de mídia.

Se a imagem estiver em um contêiner, será possível usar 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, o srcset define as imagens que você permite que o navegador selecione e o tamanho de cada uma. Para garantir que os atributos de largura e altura <img> possam ser definidos, todas as imagens precisam 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, é possível incluir uma foto cortada de uma imagem para janelas de visualização estreitas e exibir a imagem completa no computador:

<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 são compatíveis com a configuração 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 tardiamente

As imagens não são o único tipo de conteúdo que pode causar mudanças de layout. Anúncios, embeddings, iframes e outros conteúdos injetados dinamicamente podem fazer com que o conteúdo apareça depois que ele desloque para baixo, aumentando a CLS.

Os anúncios são um dos maiores contribuintes para as mudanças de layout na Web. As redes de publicidade e os editores geralmente oferecem suporte a tamanhos de anúncio dinâmicos. Os tamanhos dos anúncios aumentam o desempenho e a receita devido às taxas de cliques mais altas e ao maior número de anúncios que concorrem no leilão. Infelizmente, isso pode gerar uma experiência do usuário insatisfatória porque os anúncios enviam o conteúdo visível para baixo na página.

Os widgets incorporáveis permitem que você inclua conteúdo da web portátil em sua página, como vídeos do YouTube, mapas do Google Maps e postagens de mídia social. No entanto, esses widgets geralmente não sabem o tamanho do conteúdo antes de serem carregados. Como resultado, as plataformas que oferecem embeddings nem sempre reservam espaço para os widgets, o que causa mudanças de layout quando finalmente são carregadas.

As técnicas para lidar com isso são todas semelhantes. As principais diferenças são o controle que você tem sobre o conteúdo que será inserido. Se isso for inserido por um terceiro, como um parceiro de publicidade, talvez você não saiba o tamanho exato do conteúdo que será inserido, nem poderá controlar as mudanças de layout que ocorrerem nessas incorporações.

Reserve espaço para conteúdo com carregamento atrasado

Ao colocar conteúdo com carregamento tardio no fluxo de conteúdo, as mudanças de layout podem ser evitadas reservando o espaço para elas no layout inicial.

Uma abordagem é adicionar uma regra CSS min-height para reservar espaço ou, para conteúdo responsivo, como anúncios, por exemplo, usar a propriedade CSS aspect-ratio de maneira semelhante à maneira como os navegadores usam isso automaticamente para imagens com dimensões fornecidas.

Três dispositivos móveis com apenas conteúdo de texto no primeiro dispositivo, que é deslocado para baixo no segundo dispositivo, e reservar espaço com um marcador de posição, como mostrado no terceiro dispositivo, impede a mudança.
Reservar espaço para anúncios pode impedir mudanças de layout

Talvez seja necessário considerar diferenças sutis nos tamanhos dos anúncios ou dos marcadores de posição nos formatos usando consultas de mídia.

Para conteúdos que podem não ter uma altura fixa, como anúncios, talvez não seja possível reservar a quantidade exata de espaço necessária para eliminar a mudança de layout por completo. Se um anúncio menor for veiculado, o editor poderá estilizar um contêiner maior para evitar mudanças de layout ou escolher o tamanho mais provável para o espaço 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, você pode definir o tamanho inicial como o menor tamanho que será usado e aceitar algum nível de mudança para conteúdos maiores. O uso de min-height, como sugerido anteriormente, permite que o elemento pai cresça conforme necessário e reduz o impacto das mudanças de layout, em comparação com o tamanho padrão de 0 px de um elemento vazio.

Para evitar o recolhimento do espaço reservado, mostre um marcador se, por exemplo, nenhum anúncio for retornado. Remover o espaço reservado para elementos pode gerar a mesma CLS que inserir conteúdo.

Posicionar o conteúdo com carregamento tardio mais baixo na janela de visualização

O conteúdo injetado dinamicamente mais perto da parte de cima da janela de visualização geralmente causa mais mudanças de layout do que o conteúdo injetado mais abaixo na janela de visualização. No entanto, injetar conteúdo em qualquer lugar da janela de visualização ainda causa algumas mudanças. Se você não puder reservar espaço para conteúdo injetado, recomendamos colocá-lo mais tarde na página para reduzir o impacto na CLS.

Evitar inserir novo conteúdo sem interação do usuário

Você provavelmente já passou por mudanças de layout devido à interface que aparece na parte superior ou inferior da janela de visualização quando você tenta carregar um site. Semelhante aos anúncios, isso geralmente acontece com banners e formulários que deslocam o restante do conteúdo da página:

Conteúdo dinâmico sem espaço reservado.

Se você precisar exibir esses tipos de affordances de interface, reserve espaço suficiente na janela de visualização com antecedência (por exemplo, usando um marcador de posição ou uma interface de esqueleto) para que, quando ela for carregada, não faça o conteúdo da página mudar de forma inesperada. Como alternativa, sobreponha o conteúdo quando fizer sentido para garantir que o elemento não faça parte do fluxo do documento. Consulte a postagem Práticas recomendadas para avisos de cookies se quiser mais recomendações sobre esses tipos de componentes.

Em alguns casos, adicionar conteúdo de forma dinâmica é 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 ativo. Há várias maneiras de evitar mudanças inesperadas de layout 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. Lembre-se de desativar todos os links e controles até que a transição seja concluída para evitar cliques ou toques acidentais enquanto o novo conteúdo estiver chegando.
  • Fazer com que o usuário inicie o carregamento de novo conteúdo para não se surpreender com a mudança (por exemplo, com um botão "Carregar mais" ou "Atualizar"). É recomendável pré-buscar o conteúdo antes da interação do usuário para que ele apareça imediatamente. Como lembrete, mudanças de layout que ocorrem em até 500 milissegundos após a entrada do usuário não são contabilizadas na CLS.
  • Carregue o conteúdo facilmente 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").
Exemplos de carregamento de conteúdo dinâmico sem causar mudanças inesperadas de layout do Twitter e do site da Chloé
Exemplos de carregamento de conteúdo dinâmico sem causar mudanças inesperadas de layout. À esquerda: conteúdo do feed ao vivo carregando no Twitter. Direita: exemplo de "Load More" no site da Chloé. Confira como a equipe da YNAP otimizou a CLS ao carregar mais conteúdo.

Animações

Mudanças nos valores de propriedades CSS podem exigir que o navegador reaja a elas. Alguns valores, como box-shadow e box-sizing, acionam o novo layout, a pintura e a composição. Mudar as propriedades top e left também causa mudanças de layout, mesmo quando o elemento que está sendo movido está na própria camada. Evite animar usando essas propriedades.

Outras propriedades CSS podem ser alteradas sem acionar novos layouts. Isso inclui o uso de animações transform para translacionar, dimensionar, girar ou inclinar elementos.

Animações compostas que usam translate não podem afetar outros elementos e, portanto, não são contabilizadas na CLS. Animações não compostas também não causam novo layout. Para saber mais sobre quais propriedades CSS acionam mudanças de layout, consulte Animações de alto desempenho.

Fontes da Web

O download e a renderização de fontes da Web geralmente são processados de duas maneiras antes do download da fonte:

  • A fonte substituta é trocada pela fonte da Web, gerando um Flash de texto sem estilo (FOUT, na sigla em inglês).
  • O texto "Invisível" é exibido usando a fonte de fallback até que uma fonte da Web esteja disponível e o texto fique visível (FOIT, na sigla em inglês), que significa flash de texto invisível.

As duas abordagens podem causar mudanças de layout. Mesmo que o texto seja invisível, ele ainda será disposto usando a fonte substituta. Portanto, quando a fonte da Web é carregada, o bloco de texto e o conteúdo ao redor mudam da mesma forma que a fonte visível.

As ferramentas a seguir podem ajudar a minimizar essa mudança:

  • A font-display: optional pode evitar um novo layout, já que a fonte da Web só é usada quando está disponível no momento do layout inicial.
  • Confira se a fonte substituta adequada está sendo usada. Por exemplo, o uso de font-family: "Google Sans", sans-serif; garante que a fonte substituta sans-serif do navegador seja usada enquanto "Google Sans" é carregado. Não especificar uma fonte substituta usando apenas font-family: "Google Sans" significa que a fonte padrão será usada, o que no Chrome é "Times", uma fonte com serifa que é uma correspondência pior do que a fonte padrão sans-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-override e line-gap-override, conforme detalhado na postagem Melhorias nos substitutos de fonte.
  • A API FontLoading pode reduzir o tempo necessário para obter as fontes necessárias.
  • Carregue fontes da Web essenciais o mais cedo possível usando <link rel=preload>. Uma fonte pré-carregada terá maior chance de encontrar a primeira pintura. Nesse caso, não haverá mudança de layout.

Leia Práticas recomendadas para fontes para ver outras práticas recomendadas sobre fontes.

Reduzir a CLS garantindo que as páginas sejam 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 avanço e retorno (bfcache).

O bfcache mantém as páginas na memória dos navegadores por um curto período depois que você sai da página. Dessa forma, se você voltar a elas, elas serão restauradas exatamente como você as deixou. Isso significa que a página totalmente carregada fica disponível instantaneamente, sem nenhuma mudança que normalmente pode ser vista durante o carregamento por qualquer um dos motivos apresentados anteriormente.

Embora isso possa significar que o carregamento de página inicial encontra mudanças de layout, quando um usuário volta pelas páginas, ele não vê as mesmas mudanças várias vezes. Procure sempre evitar as mudanças mesmo no carregamento inicial, mas quando isso for mais complicado de resolver totalmente, é possível pelo menos reduzir o impacto evitando-as em qualquer navegação bfcache.

As navegações de avanço e retorno são comuns em muitos sites. Por exemplo, retornar a uma página de conteúdo, a uma página de categoria ou aos resultados da pesquisa.

Quando esse recurso foi lançado no Chrome, observamos melhorias perceptíveis na CLS.

O bfcache é usado por padrão por todos os navegadores, mas alguns sites não estão qualificados para ele por vários motivos. Leia o guia do bfcache para mais detalhes sobre como testar e identificar problemas que impeçam o uso do bfcache e aproveitar esse recurso ao máximo para ajudar na pontuação geral de CLS do site.

Conclusão

Há várias técnicas para identificar e melhorar a CLS, conforme detalhado anteriormente neste guia. Existem permissões integradas às Core Web Vitals. Portanto, mesmo que você não consiga eliminar a CLS completamente, o uso de algumas dessas técnicas pode ajudar a reduzir o impacto. Esperamos que isso permita que você fique dentro desses limites, criando uma experiência melhor para os usuários do seu site.