Cumulative Layout Shift (CLS)

Compatibilidade com navegadores

  • 77
  • 79
  • x
  • x

Origem

A Mudança de layout cumulativa (CLS) é uma métrica estável das Core Web Vitals. É uma métrica importante e centrada no usuário para medir a estabilidade visual, porque ajuda a quantificar a frequência com que os usuários experimentam mudanças inesperadas de layout. Um CLS baixo ajuda a garantir que a página seja incrível.

Mudanças inesperadas de layout podem atrapalhar a experiência do usuário de várias maneiras, fazendo com que ele se perca durante a leitura (se o texto se mover repentinamente) ou fazendo com que cliquem no link ou botão errado. Em alguns casos, isso pode causar muitos danos.

Uma mudança repentina no layout faz o usuário confirmar um pedido grande que pretendia cancelar.

A movimentação inesperada do conteúdo da página geralmente acontece quando os recursos são carregados de maneira assíncrona ou os elementos DOM são adicionados dinamicamente à página antes do conteúdo existente. A causa do movimento pode ser uma imagem ou um vídeo com dimensões desconhecidas, uma fonte renderizada maior ou menor do que a substituta ou um anúncio ou widget de terceiros que se redimensiona dinamicamente.

As diferenças entre o funcionamento de um site durante o desenvolvimento e a experiência dos usuários pioram esse problema. Exemplo:

  • O conteúdo personalizado ou de terceiros geralmente se comporta de maneira diferente no desenvolvimento e na produção.
  • As imagens de teste geralmente já estão no cache do navegador do desenvolvedor, mas levam mais tempo para carregar para o usuário final.
  • As chamadas de API executadas localmente costumam ser tão rápidas que atrasos imperceptíveis no desenvolvimento podem se tornar substanciais na produção.

A métrica Cumulative Layout Shift (CLS) ajuda a resolver esse problema medindo com que frequência isso acontece com usuários reais.

O que é CLS?

A CLS é uma medida do maior burst de pontuações de troca de layout para cada mudança inesperada que ocorre durante a vida útil de uma página.

Uma mudança de layout ocorre sempre que um elemento visível muda de posição de um frame renderizado para o próximo. Consulte a pontuação da troca de layout para ver detalhes sobre como essas mudanças são medidas.

Uma sequência de mudanças de layout, conhecida como janela de sessão, ocorre quando uma ou mais mudanças de layout individuais ocorrem em rápida sucessão, com menos de 1 segundo entre cada mudança, durante um período máximo de 5 segundos.

O maior burst é a janela de sessão com a pontuação cumulativa máxima de todas as mudanças de layout nessa janela.

Exemplo de janelas de sessão. As barras azuis representam as pontuações de cada mudança de layout individual.

O que é uma boa pontuação de CLS?

Para oferecer uma boa experiência do usuário, o site precisa ter uma pontuação de CLS de 0.1 ou menos. Para garantir que essa meta seja atingida para a maioria dos usuários, recomendamos medir o 75o percentil de carregamentos de página, segmentado em dispositivos móveis e computadores.

Os valores bons de CLS são 0,1 ou menores, os valores ruins são maiores do que 0,25 e qualquer valor intermediário precisa ser melhorado
Bons valores de CLS são 0,1 ou menos. Valores ruins são maiores que 0,25.

Para saber mais sobre a pesquisa e a metodologia por trás dessa recomendação, consulte Como definir os limites das Core Web Vitals.

Mudanças de layout em detalhes

As mudanças de layout são definidas pela API Layout Instability, que informa entradas layout-shift sempre que um elemento visível na janela de visualização muda a posição inicial (por exemplo, a posição superior e esquerda no modo de gravação padrão) entre dois frames. Os elementos que têm mudanças na posição inicial são considerados elementos instáveis.

As mudanças de layout só acontecem quando os elementos existentes mudam a posição inicial. Se um novo elemento for adicionado ao DOM ou um elemento existente mudar de tamanho, ele só será contabilizado como uma mudança de layout se a mudança fizer com que outros elementos visíveis mudem a posição inicial.

Pontuação da troca de layout

Para calcular a pontuação de mudança de layout, o navegador considera o tamanho da janela de visualização e o movimento de elementos instáveis nela entre dois frames renderizados. A pontuação da mudança de layout é um produto de duas medidas desse movimento: a fração de impacto e a fração de distância.

layout shift score = impact fraction * distance fraction

Fração de impacto

A fração de impacto mede como os elementos instáveis afetam a área da janela de visualização entre dois frames.

A fração de impacto de um determinado frame é uma combinação das áreas visíveis de todos os elementos instáveis desse frame e do frame anterior, como uma fração da área total da janela de visualização.

Exemplo de fração de impacto com um elemento instável
Se um elemento mudar de posição, a posição anterior e a atual contribuem para a fração de impacto.

Esta imagem mostra um elemento que ocupa metade da janela de visualização em um frame. No próximo frame, o elemento é deslocado 25% para baixo em relação à altura da janela de visualização. O retângulo pontilhado vermelho indica a área visível do elemento sobre os dois frames, que, nesse caso, é 75% da janela de visualização total. Portanto, a fração de impacto é 0.75.

Fração da distância

A outra parte da equação da pontuação de mudança de layout mede a distância que elementos instáveis se moveram em relação à janela de visualização. A fração de distância é a maior distância horizontal ou vertical que qualquer elemento instável moveu no frame dividida pela maior dimensão da janela de visualização (largura ou altura, o que for maior).

Exemplo de fração de distância com um elemento instável
A fração de distância mede o quanto um elemento foi movido na janela de visualização.

Nesse exemplo, a maior dimensão da janela de visualização é a altura, e o elemento instável foi movido 25% dessa altura, o que torna a fração de distância 0.25.

Uma fração de impacto de 0.75 e uma fração de distância de 0.25 produzem uma pontuação de mudança de layout de 0.75 * 0.25 = 0.1875.

Exemplos

O próximo exemplo ilustra como a adição de conteúdo a um elemento existente afeta a pontuação da mudança de layout:

Exemplo de mudança de layout com vários elementos estáveis e _instáveis_
Adicionar um botão à parte de baixo da caixa cinza empurra a caixa verde para baixo e parcialmente para fora da janela de visualização.

Neste exemplo, a caixa cinza muda de tamanho, mas a posição inicial não muda, então não é um elemento instável.

O botão "Click Me!" não estava no DOM anteriormente, então a posição inicial dele também não mudou.

A posição inicial da caixa verde muda, mas foi movida em parte para fora da janela de visualização, e a área invisível não é considerada no cálculo da fração de impacto. A união das áreas visíveis da caixa verde em ambos os frames (o retângulo tracejado vermelho) é a mesma que a área da caixa verde no primeiro frame: 50% da janela de visualização. A fração de impacto é 0.5.

A fração de distância é ilustrada pela seta azul. A caixa verde foi movida para baixo em cerca de 14% da janela de visualização, então a fração de distância é 0.14.

A pontuação da troca de layout é 0.5 x 0.14 = 0.07.

O exemplo abaixo mostra como vários elementos instáveis afetam a pontuação da mudança de layout de uma página:

Exemplo de mudança de layout com _elementos instáveis_ e recorte da janela de visualização
À medida que mais nomes aparecem nessa lista classificada, os nomes atuais são movidos para preservar a ordem alfabética.

O primeiro item da lista ("Cat") não muda a posição inicial entre frames, então ele fica estável. Os novos itens adicionados à lista não estavam anteriormente no DOM, então as posições iniciais deles também não mudam. No entanto, os itens rotulados como "Cachorro", "Cavalo" e "Zebra" mudam de posição inicial, tornando-os elementos instáveis.

Novamente, o retângulo tracejado vermelho representa a área desses três elementos instáveis antes e depois da mudança, que nesse caso é cerca de 60% da área da janela de visualização (fração de impacto de 0.60).

As setas representam as distâncias que elementos instáveis passaram das posições iniciais. O elemento "Zebra", representado pela seta azul, foi o mais movido, em cerca de 30% da altura da janela de visualização. Isso torna a fração da distância neste exemplo 0.3.

A pontuação da troca de layout é 0.60 x 0.3 = 0.18.

Mudanças de layout esperadas e inesperadas

Nem todas as trocas de layout são ruins. Muitos aplicativos da Web dinâmicos frequentemente mudam a posição inicial dos elementos na página. Uma mudança de layout só é ruim se o usuário não estiver esperando.

Mudanças de layout iniciadas pelo usuário

Mudanças de layout que ocorrem em resposta a interações do usuário (como clicar ou tocar em um link, pressionar um botão ou digitar em uma caixa de pesquisa) geralmente são simples, desde que a mudança ocorra perto o suficiente da interação para que a relação fique clara para o usuário.

Por exemplo, se uma interação do usuário acionar uma solicitação de rede que pode levar um tempo para ser concluída, é melhor criar um espaço imediatamente e mostrar um indicador de carregamento para evitar uma mudança de layout desagradável quando a solicitação for concluída. Se o usuário não perceber que algo está sendo carregado ou não tiver uma ideia de quando o recurso estará pronto, ele poderá tentar clicar em outro item enquanto aguarda, e esse outro elemento poderá sair de baixo quando o primeiro terminar de carregar.

Mudanças de layout que ocorrem até 500 milissegundos após a entrada do usuário terão a flag hadRecentInput definida para que você possa excluí-las dos cálculos.

Animações e transições

Animações e transições, quando bem-feitas, são uma ótima maneira de atualizar o conteúdo na página sem surpreender o usuário. Conteúdo que muda de forma abrupta e inesperada na página quase sempre cria uma experiência do usuário ruim. No entanto, o conteúdo que se move de maneira gradual e natural de uma posição para outra pode ajudar o usuário a entender melhor o que está acontecendo e orientá-lo entre as mudanças de estado.

Respeite as configurações do navegador prefers-reduced-motion, porque a animação pode causar problemas de integridade ou de atenção para alguns visitantes do site.

A propriedade CSS transform permite animar elementos sem acionar mudanças de layout:

  • Use transform: scale() em vez de alterar as propriedades height e width.
  • Para mover elementos, use transform: translate() em vez de mudar as propriedades top, right, bottom ou left.

Como medir a CLS

A CLS pode ser medida no laboratório ou no campo e está disponível nas ferramentas a seguir.

Ferramentas de campo

Ferramentas de laboratório

Medir mudanças de layout em JavaScript

Para medir as mudanças de layout em JavaScript, use a API Layout Instability.

O exemplo a seguir mostra como criar um PerformanceObserver para registrar entradas layout-shift no console:

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('Layout shift:', entry);
  }
}).observe({type: 'layout-shift', buffered: true});

Medir a CLS no JavaScript

Para medir a CLS em JavaScript, agrupe as entradas layout-shift inesperadas em que você fez login e calcule o valor máximo da sessão. Para uma implementação de referência, consulte o código-fonte da biblioteca JavaScript web vitals.

Na maioria dos casos, o valor do CLS no momento em que a página está sendo descarregada é o valor final da página, mas há algumas exceções importantes listadas na próxima seção. A biblioteca JavaScript web vitals considera isso o máximo possível, dentro das limitações das APIs da Web.

Diferenças entre a métrica e a API

  • Se uma página for carregada em segundo plano ou se estiver em segundo plano antes de o navegador exibir qualquer conteúdo, ela não deverá relatar nenhum valor de CLS.
  • Se uma página for restaurada do cache de avanço e retorno, o valor da CLS precisará ser redefinido como zero, porque isso é feito para os usuários como uma visita à página distinta.
  • A API não informa entradas layout-shift para mudanças que ocorrem em iframes, mas a métrica sim porque elas fazem parte da experiência do usuário na página. Isso pode mostrar uma diferença entre o CrUX e o RUM. Para medir a CLS corretamente, você precisa incluir iframes. Os subframes podem usar a API para informar as entradas layout-shift ao frame pai para agregação.

Além dessas exceções, o CLS tem ainda mais complexidade porque mede toda a vida útil de uma página:

  • Os usuários podem manter uma guia aberta por muito tempo, como dias, semanas e até meses. Na verdade, é possível que um usuário nunca feche uma guia.
  • Em sistemas operacionais para dispositivos móveis, os navegadores normalmente não executam callbacks de descarregamento de páginas para guias em segundo plano, dificultando o relatório do valor "final".

Para lidar com esses casos, recomendamos que o sistema informe a CLS sempre que uma página estiver em segundo plano e sempre que ela for descarregada. O evento visibilitychange abrange ambos os cenários. Os sistemas de análise que recebem esses dados precisarão calcular o valor final do CLS no back-end.

Em vez de memorizar e lidar com todos esses casos por conta própria, os desenvolvedores podem usar a biblioteca JavaScript web-vitals para medir a CLS, que considera tudo o que foi mencionado aqui, exceto o caso do iframe:

import {onCLS} from 'web-vitals';

// Measure and log CLS in all situations
// where it needs to be reported.
onCLS(console.log);

Como melhorar a CLS

Para mais orientações sobre como identificar mudanças de layout no campo e usar dados de laboratório para otimizá-las, consulte nosso guia sobre como otimizar a CLS.

Outros recursos

Registro de alterações

Às vezes, bugs são descobertos nas APIs usadas para medir as métricas e, às vezes, nas definições das próprias métricas. Por isso, às vezes é necessário fazer alterações, que podem aparecer como melhorias ou regressões nos seus relatórios e painéis internos.

Para ajudar você a gerenciar isso, todas as mudanças na implementação ou definição dessas métricas são exibidas neste registro de alterações.

Se você tiver feedback sobre essas métricas, envie-o no Grupo do Google web-vitals-feedback.