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.
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.
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.
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.
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).
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:
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:
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 propriedadesheight
ewidth
. - Para mover elementos, use
transform: translate()
em vez de mudar as propriedadestop
,right
,bottom
ouleft
.
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
- Relatório de experiência do usuário do Chrome
- PageSpeed Insights
- Search Console (relatório de Core Web Vitals)
- Biblioteca JavaScript
web-vitals
Ferramentas de laboratório
- Chrome DevTools (link em inglês)
- Farol
- PageSpeed Insights
- WebPageTest
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 entradaslayout-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
- Orientação da Tag do editor do Google sobre como minimizar a mudança de layout
- Understanding Cumulative Layout Shift, por Annie Sullivan e Steve Kobes em #PerfMatters (2020)
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.