Saiba como evitar mudanças repentinas de layout para melhorar a experiência do usuário
A Cumulative Layout Shift (CLS) é uma das três métricas das Core Web Vitals. Ele mede a instabilidade do conteúdo combinando a quantidade de conteúdo visível que mudou 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, os elementos mudam ao redor da página, tirando você do lugar e exigindo que você encontre seu lugar novamente. Isso é muito comum na Web, inclusive ao ler notícias ou tentar clicar em "Pesquisar" ou "Adicionar ao carrinho" botões. Essas experiências são visualmente desagradáveis e frustrantes. Isso geralmente acontece quando elementos visíveis são forçados a se mover porque outro elemento foi adicionado à página ou redimensionado repentinamente.
Para oferecer uma boa experiência ao usuário, os sites precisam ter uma CLS de 0,1 ou menos em pelo menos 75% das visitas à página.
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 de acordo com o cálculo da quantidade de conteúdo que está mudando e a distância que ele percorre.
Neste guia, falaremos sobre a otimização de 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 de CLS e de onde vêm as mudanças.
CLS em ferramentas de laboratório versus campo
É comum ouvir os desenvolvedores pensarem que a CLS medida pelo Chrome UX Report (CrUX, na sigla em inglês) está incorreta, porque não corresponde à CLS que eles medem usando o Chrome DevTools ou outras ferramentas de laboratório. As ferramentas do Laboratório de desempenho da Web, como o Lighthouse, podem não mostrar a CLS completa de uma página, porque normalmente fazem um carregamento simples da página para medir algumas métricas de desempenho da Web e fornecer orientação. No entanto, os fluxos de usuário do Lighthouse permitem medir além da auditoria de carregamento de página padrão.
O CrUX é o conjunto de dados oficial do programa Web Vitals e, para isso, é medido ao longo de toda a vida útil da página, e não apenas durante o carregamento inicial, que as ferramentas de laboratório normalmente medem.
Mudanças de layout são muito comuns durante o carregamento da página, porque 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 porque são mudanças esperadas, desde que ocorram dentro de 500 milissegundos após a interação.
No entanto, outras mudanças pós-carregamento inesperadas pelo usuário podem ser incluídas onde não houve interação qualificada. Por exemplo, se você rolar a página para avançar e o conteúdo de carregamento lento for carregado, causando mudanças. Outras causas comuns de CLS pós-carregamento são em interações de transições, por exemplo, em aplicativos de página única, que levam mais do que o período de carência de 500 milissegundos.
O PageSpeed Insights mostra os dados CLS de um URL em "Descubra o que seus usuários reais estão enfrentando" seção e o CLS de carga baseado em laboratório na seção "Diagnosticar problemas de desempenho" nesta seção. As diferenças entre esses valores provavelmente são resultado de CLS pós-carregamento.
Identificar problemas de CLS de carga
Quando as pontuações de CLS do CrUX e do Lighthouse no PageSpeed Insights estão amplamente alinhadas, isso geralmente indica que um problema de CLS de carga foi 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 para o carregamento de página junto com a contribuição de CLS. É possível conferir essas auditorias filtrando as auditorias de CLS:
O painel Performance no DevTools também destaca as mudanças de layout na seção Experiência. A visualização Summary de um registro Layout Shift
inclui a pontuação cumulativa da troca de layout, bem como uma sobreposição de retângulo mostrando as regiões afetadas. Isso é particularmente útil para conferir mais detalhes sobre os problemas de CLS de carga, já que eles são facilmente replicados com um perfil de desempenho de recarga.
Identificar problemas de CLS pós-carregamento
A divergência entre as pontuações de CrUX e de CLS do Lighthouse geralmente indica o CLS pós-carregamento. Pode ser difícil acompanhar essas mudanças 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 um aviso ou no console, onde é possível conferir mais detalhes sobre os elementos deslocados.
Como alternativa ao uso da extensão, você pode navegar na sua página da Web enquanto grava mudanças de layout usando um Observador de Desempenho colado no console.
Depois de configurar o monitoramento de turno, tente replicar os problemas de CLS pós-carregamento. A CLS geralmente acontece enquanto o usuário rola por uma página, quando o conteúdo de carregamento lento é carregado totalmente 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 qualquer uma dessas interações conta como inesperada, mesmo que aconteça dentro de 500 milissegundos.
Para saber mais, consulte Depurar trocas de layout.
Depois de identificar as causas comuns de CLS, o modo de fluxo do usuário de períodos do Lighthouse também pode ser usado para garantir que os fluxos de usuários típicos não regressem com a introdução de 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 afunilar as possíveis causas. Como a maioria das ferramentas de laboratório, as ferramentas de campo medem apenas os elementos que mudaram, mas isso geralmente fornece informações suficientes para identificar a causa. Você também pode usar as medições de campo de CLS para determinar quais problemas são de maior prioridade 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 forma semelhante.
Causas comuns de CLS
Depois de identificar as causas da CLS, comece a trabalhar na correção dos 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
nas imagens e nos elementos de vídeo. Como alternativa, reserve o espaço necessário com CSS aspect-ratio
ou semelhante. 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
No início da Web, os desenvolvedores adicionavam os 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. Esses "pixels" garantiria que o navegador reservasse uma área de 640 x 360 no layout da página. A imagem se expandiria para caber nesse espaço, independentemente de as dimensões verdadeiras corresponderem a ele.
Quando o Web design responsivo foi lançado, os desenvolvedores começaram a omitir width
e height
e a usar CSS para redimensionar imagens:
img {
width: 100%; /* or max-width: 100%; */
height: auto;
}
No entanto, como o tamanho da imagem não foi especificado, não é possível alocar espaço para ela até que o navegador comece a fazer o download e possa determinar as dimensões. Conforme as imagens são carregadas, o texto desloca-se para baixo na página para criar espaço, criando uma experiência do usuário confusa e frustrante.
É aqui que entra a proporção. A proporção de uma imagem é a proporçã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 conhecemos uma das dimensões, a outra pode 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 640 px, a altura será 640 x (9 / 16) = 360 px
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áticas recomendadas modernas para definir dimensões de imagem
Como os navegadores mais recentes definem a proporção padrão das imagens com base na
atributos width
e height
da 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. Ela fornece essas informações logo no início do cálculo do layout. Quando uma imagem é determinada para ter uma determinada largura (por exemplo, width: 100%
), a proporção é usada para calcular a altura.
O valor de aspect-ratio
é calculado pelos principais navegadores conforme o HTML é processado, em vez de usar uma folha de estilo padrão do user agent (consulte esta postagem para saber mais sobre os motivos). Portanto, o valor é exibido de maneira um pouco diferente. Por exemplo, o Chrome o exibe desta forma na seção "Estilos" do painel "Elemento":
img[Attributes Style] {
aspect-ratio: auto 640 / 360;
}
O Safari se comporta de forma semelhante, usando uma fonte de estilo Atributos HTML. O Firefox não exibe 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 após o download da imagem. Se as dimensões da imagem forem diferentes, isso ainda causará alguma mudança no layout após o carregamento da imagem. No entanto, isso 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, ela ainda causa menos mudanças de layout do que o tamanho padrão de 0 x 0 de uma imagem sem dimensões.
Para saber mais sobre a proporção e pensar melhor em imagens responsivas, confira o carregamento de página sem instabilidade com proporções de mídia.
Se a imagem estiver em um contêiner, você poderá usar CSS para redimensionar a imagem 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 do <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"
/>
Suas imagens as proporções também podem mudar dependendo direção de arte. Por exemplo, talvez você queira incluir uma captura cortada de uma imagem para janelas de visualização 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
no
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 com atraso
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 deslocado para baixo, aumentando seu CLS.
Os anúncios são um dos maiores responsáveis pelas mudanças de layout na Web. As redes de anúncios e os editores geralmente oferecem suporte a tamanhos de anúncios dinâmicos. Os tamanhos dos anúncios aumentam a performance/receita devido às taxas de cliques mais altas e à maior quantidade de anúncios concorrendo no leilão. Infelizmente, isso pode resultar em uma experiência do usuário insatisfatória, já que os anúncios exibem o conteúdo que você visualiza na parte inferior da 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 mídias sociais. No entanto, esses widgets geralmente não reconhecem 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 são finalmente 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 acontecem nessas incorporações.
Reserve espaço para conteúdo carregado depois
Ao colocar conteúdo com carregamento tardio no fluxo de conteúdo, é possível evitar mudanças no layout 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 essa propriedade automaticamente para imagens com dimensões fornecidas.
Talvez você precise considerar diferenças sutis nos tamanhos de anúncios ou marcadores de posição nos formatos usando consultas de mídia.
Para conteúdo que não tem uma altura fixa, como anúncios, pode não ser possível reservar a quantidade exata de espaço necessária para eliminar completamente 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 espaço de anúncio com base nos 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 para o menor tamanho que será usado e aceitar algum nível de mudança para conteúdo maior. 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.
Evite recolher o espaço reservado mostrando um marcador se, por exemplo, nenhum anúncio for retornado. Remover o espaço reservado para elementos pode causar tanto CLS quanto inserir conteúdo.
Posicionar o conteúdo de carregamento atrasado na janela de visualização
O conteúdo injetado dinamicamente mais próximo da parte superior da janela de visualização geralmente causa mais trocas 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 não for possível reservar espaço para conteúdo injetado, recomendamos colocá-lo mais tarde na página para reduzir o impacto na CLS.
Evite inserir conteúdo novo sem uma interação do usuário
Provavelmente você já passou por mudanças de layout devido à interface que aparece na parte de cima ou de baixo da janela de visualização ao tentar carregar um site. Assim como nos anúncios, isso geralmente acontece com banners e formulários que deslocam o restante do conteúdo da página:
Se você precisar exibir esses tipos de recursos de interface, reserve espaço suficiente na janela de visualização com antecedência (por exemplo, usando um marcador de posição ou interface de esqueleto) para que, quando ele for carregado, o conteúdo da página não se mova de maneira surpreendente. Como alternativa, sobreponha o conteúdo onde necessário para garantir que o elemento não faça parte do fluxo do documento. Consulte a postagem Práticas recomendadas para avisos de cookies para conferir 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 publicado. 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 é disponibilizado.
- Faça com que o usuário inicie o carregamento de novo conteúdo, para que ele não se surpreenda com a mudança (por exemplo, com um botão "Carregar mais" ou "Atualizar"). É recomendável fazer uma pré-busca do 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.
- O conteúdo é carregado sem interrupções fora da tela e sobrepõe 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 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 traduzir, 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 feitos de duas maneiras antes do download:
- A fonte substituta é trocada pela fonte da web, o que resulta em um Flash de texto sem estilo (FOUT, na sigla em inglês).
- "Invisível" o texto será exibido com a fonte substituta até que uma fonte da web 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 seja invisível, ele ainda é apresentado usando a fonte substituta. Portanto, quando a fonte da Web é carregada, o bloco de texto e o conteúdo ao redor mudam da mesma maneira que para a fonte visível.
As ferramentas a seguir podem ajudar a minimizar a mudança de texto:
- O
font-display: optional
pode evitar um novo layout, já que a fonte da Web só será usada se estiver disponível no momento do layout inicial. - Use a fonte substituta apropriada. Por exemplo, usar
font-family: "Google Sans", sans-serif;
garante que a fonte substitutasans-serif
do navegador seja usada enquanto"Google Sans"
é carregado. Não especificar uma fonte substituta usando apenasfont-family: "Google Sans"
vai fazer com que a fonte padrão seja usada, que no Chrome é "Times", uma fonte com serifa que tem uma correspondência pior do que a fontesans-serif
padrão. - 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
eline-gap-override
, conforme detalhado na postagem Substitutos de fonte aprimorados. - A Font Load API pode reduzir o tempo necessário para gerar as fontes necessárias.
- Carregue fontes da Web essenciais o quanto antes usando
<link rel=preload>
. Uma fonte pré-carregada terá mais chance de encontrar a first paint, em que não há mudança de layout.
Leia Práticas recomendadas para fontes para conferir outras práticas recomendadas relacionadas a fontes.
Reduza o 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 sejam qualificadas para o cache de avanço e retorno (bfcache).
O bfcache mantém as páginas na memória do navegador por um curto período depois que você sai da página. Assim, se você voltar a elas, elas serão restauradas exatamente como foram deixadas. Isso significa que a página totalmente carregada fica disponível instantaneamente, sem mudanças que podem ser vistas normalmente durante o carregamento por qualquer um dos motivos mencionados anteriormente.
Embora isso potencialmente ainda signifique que o carregamento da página inicial encontra mudanças de layout, quando um usuário volta pelas páginas, ele não vê o mesmo layout alterado repetidamente. Você sempre deve tentar evitar as mudanças, mesmo no carregamento inicial, mas quando isso for mais complicado de resolver por completo, é possível pelo menos reduzir o impacto evitando-as em qualquer navegação no bfcache.
Navegações de retorno e avanço são comuns 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 para o Chrome, notamos melhorias perceptíveis na CLS (link em inglês).
O bfcache é usado por padrão por todos os navegadores, mas alguns sites não são qualificados para o bfcache por vários motivos. Leia o guia do bfcache (em inglês) para mais detalhes sobre como testar e identificar problemas que impedem o uso do bfcache e aproveitar ao máximo esse recurso para ajudar na pontuação geral de CLS do seu site.
Conclusão
Conforme detalhado anteriormente neste guia, existem várias técnicas para identificar e melhorar a CLS. Existem permissões integradas às Core Web Vitals. Portanto, mesmo que não seja possível eliminar a CLS completamente, o uso de algumas dessas técnicas permitirá 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.