Uma coleção das práticas recomendadas que a equipe do Chrome DevRel acredita serem as maneiras mais eficazes de melhorar o desempenho das Core Web Vitals em 2023.
Ao longo dos anos, o Google fez muitas recomendações para desenvolvedores Web sobre como melhorar o desempenho.
Embora cada uma dessas recomendações, individualmente, possa melhorar o desempenho para muitos sites, o conjunto completo de recomendações é admitidamente complexo e, de maneira realista, não há como uma pessoa ou site poderia seguir todas elas.
A menos que o desempenho na Web seja seu trabalho diário, provavelmente não será óbvio quais recomendações terão o maior impacto positivo em seu site. Por exemplo, talvez você tenha lido que implementar CSS crítico pode melhorar o desempenho de carregamento e também pode ter ouvido falar que é importante otimizar suas imagens. Mas, se você não tem tempo para trabalhar nas duas coisas, como decidiria qual escolher?
Na equipe do Chrome, passamos o ano passado tentando responder a esta pergunta: quais são as recomendações mais importantes que podemos dar aos desenvolvedores para ajudá-los a melhorar o desempenho dos usuários?
Para responder adequadamente a essa pergunta, temos que considerar não apenas os méritos técnicos de qualquer recomendação, mas também fatores humanos e organizacionais que influenciam a probabilidade de os desenvolvedores realmente serem capazes de adotar essas recomendações. Em outras palavras, algumas recomendações podem ter um impacto enorme na teoria, mas, na realidade, poucos sites terão tempo ou recursos para implementá-las. Da mesma forma, algumas recomendações são essenciais, mas a maioria dos sites já segue essas práticas.
Em resumo, queríamos que nossa lista de principais recomendações de desempenho na Web se concentrasse em:
- Recomendações que acreditamos ter o maior impacto no mundo real
- Recomendações que são relevantes e aplicáveis à maioria dos sites
- Recomendações realistas para a maioria dos desenvolvedores implementar
Ao longo do último ano, passamos muito tempo auditando todo o conjunto de recomendações de desempenho que fazemos e avaliando cada uma delas (qualitativa e quantitativamente) de acordo com os três critérios acima.
Esta postagem descreve nossas principais recomendações para melhorar o desempenho de cada uma das Core Web Vitals. Se você não tem muita experiência com desempenho na Web ou está tentando decidir qual será o melhor custo-benefício, essas recomendações são o melhor ponto de partida.
Maior exibição de conteúdo (LCP)
Nossas primeiras recomendações são para a Maior exibição de conteúdo (LCP), que é uma medida de desempenho do carregamento. Das três métricas das Core Web Vitals, a LCP é aquela com que o maior número de sites tem dificuldades. Atualmente, apenas cerca da metade de todos os sites na Web atinge o limite recomendado. Então, vamos começar por aí.
Verifique se o recurso de LCP é detectável na origem HTML
De acordo com o Web Almanac de 2022 do HTTP Archive, 72% das páginas para dispositivos móveis têm uma imagem como elemento da LCP. Isso significa que, para a maioria dos sites otimizar a LCP, será necessário garantir que essas imagens sejam carregadas rapidamente.
O que pode não ser óbvio para muitos desenvolvedores é que o tempo necessário para carregar uma imagem é apenas uma parte do desafio. Outra parte importante é o tempo antes de uma imagem começar a carregar, e os dados do Arquivo HTTP sugerem que esse é o momento em que muitos sites travam.
Na verdade, das páginas em que o elemento da LCP era uma imagem, 39% delas tinham URLs de origem que não eram detectáveis pela origem do documento HTML. Em outras palavras, esses URLs não foram encontrados em atributos HTML padrão (como <img src="...">
ou <link rel="preload" href="...">
), o que permitiria ao navegador encontrá-los rapidamente e começar a carregá-los imediatamente.
Se uma página tiver que esperar até que os arquivos CSS ou JavaScript sejam totalmente baixados, analisados e processados antes que a imagem comece a ser carregada, talvez seja tarde demais.
Como regra geral, se o elemento da LCP for uma imagem, o URL da imagem deverá sempre ser descoberto na fonte HTML. Algumas dicas para tornar isso possível são:
Carregue a imagem usando um elemento
<img>
com o atributosrc
ousrcset
. Não use atributos não padrão, comodata-src
, que exigem JavaScript para a renderização, porque eles sempre são mais lentos. 9% das páginas ocultam a imagem da LCP atrás dedata-src
.Prefira a renderização do lado do servidor (SSR) em vez da renderização do lado do cliente (CSR, na sigla em inglês), já que a SSR implica que a marcação de página completa (incluindo a imagem) está presente no código-fonte HTML. As soluções CSR exigem que o JavaScript seja executado antes que a imagem possa ser descoberta.
Caso sua imagem precise ser referenciada em um arquivo CSS ou JS externo, você ainda poderá incluí-la no código-fonte HTML usando uma tag
<link rel="preload">
. As imagens referenciadas por estilos inline não são detectáveis pelo verificador de pré-carregamento do navegador. Portanto, mesmo que elas sejam encontradas na fonte HTML, a descoberta delas ainda pode ser bloqueada no carregamento de outros recursos. Por isso, o pré-carregamento pode ajudar nesses casos.
Para ajudar você a entender se a imagem LCP está com problemas de detecção, o Lighthouse vai lançar uma nova auditoria na versão 10.0 (previsto para janeiro de 2023).
Garantir que o recurso de LCP seja detectável na fonte HTML pode gerar melhorias mensuráveis e também abre oportunidades adicionais para priorizar o recurso, que é nossa próxima recomendação.
Priorize o recurso de LCP
Garantir que o recurso de LCP possa ser descoberto da fonte HTML é uma primeira etapa fundamental para garantir que o recurso de LCP possa começar a ser carregado antecipadamente. No entanto, outra etapa importante é garantir que o carregamento desse recurso seja priorizado e não fique na fila atrás de vários outros recursos menos importantes.
Por exemplo, mesmo que a imagem LCP esteja presente no código-fonte HTML usando uma tag <img>
padrão, se a página incluir uma dúzia de tags <script>
no arquivo <head>
do documento antes da tag <img>
, poderá levar algum tempo até que o recurso de imagem comece a ser carregado.
A maneira mais fácil de resolver esse problema é fornecer uma dica ao navegador sobre quais recursos têm a maior prioridade, definindo o novo atributo fetchpriority="high"
na tag <img>
ou <link>
que carrega sua imagem LCP. Isso instrui o navegador a carregá-lo mais cedo, em vez de esperar que os scripts sejam concluídos.
De acordo com o Web Almanac, apenas 0, 03% das páginas qualificadas estão aproveitando essa nova API.Isso significa que há muitas oportunidades para a maioria dos sites da Web melhorar a LCP com muito pouco trabalho. Embora o atributo fetchpriority
seja atualmente compatível apenas com navegadores baseados no Chromium, essa API é uma melhoria progressiva que outros navegadores simplesmente ignoram. Por isso, recomendamos que os desenvolvedores a usem agora.
Para navegadores que não são do Chromium, a única maneira de garantir que o recurso de LCP seja priorizado acima de outros recursos é mencioná-lo em uma parte anterior do documento. Usando o exemplo novamente de um site com muitas tags <script>
no <head>
do documento, se você quiser garantir que seu recurso de LCP seja priorizado antes dos recursos de script, adicione uma tag <link rel="preload">
antes de qualquer um desses scripts ou mova esses scripts para abaixo de <img>
posteriormente no <body>
. Embora esse recurso funcione, ele é menos ergonômico do que usar o fetchpriority
. Esperamos que outros navegadores ofereçam suporte em breve.
Outro aspecto importante da priorização do recurso de LCP é garantir que você não faça nada que cause a redução de prioridade dele, como adicionar o atributo loading="lazy"
. Hoje, 10% das páginas definem loading="lazy"
na imagem da LCP. Tenha cuidado com soluções de otimização de imagens que aplicam indiscriminadamente o comportamento de carregamento lento a todas as imagens. Se elas oferecerem uma maneira de substituir esse comportamento, use-as para a imagem da LCP. Se você não tiver certeza de qual imagem será a LCP, tente usar a heurística para escolher um candidato razoável.
Adiar recursos não críticos é outra maneira de aumentar efetivamente a prioridade relativa do recurso de LCP. Por exemplo, os scripts que não fazem a interface do usuário funcionar (como scripts de análise ou widgets sociais) podem ser adiados com segurança até depois do disparo do evento load
. Isso garante que eles não concorram com outros recursos críticos (como o de LCP) pela largura de banda da rede.
Para resumir, siga estas práticas recomendadas para garantir que o recurso de LCP seja carregado com antecedência e em alta prioridade:
- Adicione
fetchpriority="high"
à tag<img>
da sua imagem LCP. Se o recurso de LCP for carregado usando uma tag<link rel="preload">
, não se preocupe, porque você também pode definirfetchpriority="high"
nele. - Nunca defina
loading="lazy"
na tag<img>
da sua imagem LCP. Isso vai diminuir a prioridade da imagem e atrasar o carregamento dela. - Adie recursos não críticos quando possível. Mova-os para o final do documento, usando o carregamento lento nativo para imagens ou iframes, ou carregue-os de forma assíncrona via JavaScript.
Use uma CDN para otimizar o TTFB de documentos e recursos
As duas recomendações anteriores tinham como foco garantir que o recurso de LCP fosse descoberto cedo e priorizado para que ele possa começar a ser carregado imediatamente. A última peça desse quebra-cabeça é garantir que a resposta inicial ao documento chegue o mais rápido possível também.
O navegador não pode começar a carregar sub-recursos até receber o primeiro byte da resposta inicial do documento HTML e, quanto mais cedo isso acontecer, mais cedo tudo o mais poderá começar a acontecer também.
Esse tempo é conhecido como Tempo até o primeiro byte (TTFB, na sigla em inglês), e a melhor maneira de reduzir o TTFB é:
- Disponibilizar seu conteúdo geograficamente o mais próximo possível dos usuários
- Armazene em cache esse conteúdo para que o conteúdo solicitado recentemente possa ser veiculado novamente com rapidez.
A melhor maneira de fazer isso é usando uma CDN. As CDNs distribuem seus recursos para os servidores de borda, que estão espalhados por todo o mundo, limitando a distância que esses recursos precisam percorrer para seus usuários. As CDNs também costumam ter controles refinados de armazenamento em cache que podem ser personalizados e otimizados para as necessidades do seu site.
Muitos desenvolvedores estão familiarizados com o uso de um CDN para hospedar ativos estáticos, mas os CDNs também podem exibir e armazenar em cache documentos HTML, mesmo aqueles que são gerados dinamicamente.
De acordo com o Web Almanac, apenas 29% das solicitações de documentos HTML foram veiculadas a partir de uma CDN, o que significa que há uma oportunidade significativa para os sites conseguirem economizar.
Confira algumas dicas para configurar suas CDNs:
- Considere aumentar por quanto tempo o conteúdo é armazenado em cache. Por exemplo, é realmente essencial que o conteúdo esteja sempre atualizado? Ou podem ficar desatualizados por alguns minutos?).
- É possível armazenar o conteúdo em cache por tempo indefinido e depois limpar o cache se/quando você fizer uma atualização.
- Verifique se é possível mover para a borda a lógica dinâmica atualmente em execução no servidor de origem (um recurso da maioria das CDNs modernas).
Em geral, sempre que é possível veicular conteúdo diretamente da borda (evitando uma viagem ao servidor de origem), há um ganho de desempenho. Mesmo nos casos em que você precisa fazer a jornada de volta ao servidor de origem, as CDNs geralmente são otimizadas para fazer isso com muito mais rapidez.
Cumulative Layout Shift (CLS)
O próximo conjunto de recomendações é para a Cumulative Layout Shift (CLS, na sigla em inglês), que é uma medida de estabilidade visual em páginas da Web. Embora a CLS tenha melhorado muito na Web desde 2020, cerca de um quarto dos sites ainda não atinge o limite recomendado. Portanto, muitos sites ainda têm uma grande oportunidade de melhorar a experiência do usuário.
Definir tamanhos explícitos em qualquer conteúdo carregado da página
As mudanças de layout geralmente acontecem quando o conteúdo existente é movido depois que outro conteúdo termina de carregar. Portanto, a principal maneira de atenuar isso é reservar qualquer espaço necessário com antecedência, o máximo possível.
A maneira mais direta de corrigir mudanças de layout causadas por imagens sem tamanho é definir explicitamente os atributos width
e height
(ou propriedades CSS equivalentes). No entanto, de acordo com o HTTP Archive, 72% das páginas têm pelo menos uma imagem sem tamanho. Sem um tamanho explícito, os navegadores definirão inicialmente uma altura padrão de 0px
e poderão causar uma mudança perceptível no layout quando a imagem for finalmente carregada e as dimensões forem descobertas. Isso representa uma enorme oportunidade para a Web coletiva, e exige muito menos esforço do que algumas das outras recomendações sugeridas neste artigo.
Também é importante ter em mente que as imagens não são as únicas contribuições para a CLS. As mudanças de layout podem ser causadas por outros conteúdos que normalmente são carregados após a renderização inicial da página, incluindo anúncios de terceiros ou vídeos incorporados. A propriedade aspect-ratio
pode ajudar a combater isso. Trata-se de um recurso CSS relativamente novo que permite aos desenvolvedores fornecer explicitamente uma proporção para imagens e elementos que não sejam imagens. Isso permitirá que você defina uma width
dinâmica (por exemplo, com base no tamanho da tela) e faça com que o navegador calcule automaticamente a altura apropriada, da mesma forma que faz para imagens com dimensões.
Às vezes, não é possível saber o tamanho exato do conteúdo dinâmico, pois ele é, por sua natureza, dinâmico. No entanto, mesmo que você não saiba o tamanho exato, ainda pode tomar medidas para reduzir a gravidade das mudanças de layout. Configurar um min-height
sensível é quase sempre melhor do que permitir que o navegador use a altura padrão de 0px
para um elemento vazio. Usar uma min-height
também costuma ser uma solução fácil, já que ela ainda permite que o contêiner cresça até a altura final do conteúdo, se necessário. Ela apenas reduziu esse crescimento do valor total para um nível possivelmente mais tolerável.
Verifique se as páginas estão qualificadas para o bfcache
Os navegadores usam um mecanismo de navegação chamado cache de avanço e retorno, ou bfcache, para carregar instantaneamente uma página anterior ou posterior no histórico do navegador diretamente de um instantâneo da memória.
O bfcache é uma otimização significativa de desempenho no nível do navegador e elimina totalmente as mudanças de layout durante o carregamento da página, que é onde ocorre a maior parte da CLS em muitos sites. A introdução do bfcache causou a maior melhoria no CLS que observamos em 2022.
Apesar disso, um número significativo de sites não está qualificado para o bfcache e, portanto, está perdendo essa vantagem de desempenho sem custo financeiro na Web para um número significativo de navegações. A menos que sua página esteja carregando informações sensíveis que você não quer que sejam restauradas da memória, verifique se as páginas estão qualificadas.
Os proprietários dos sites precisam verificar se as páginas estão qualificadas para o bfcache e trabalhar para resolver os problemas. O Chrome já tem um testador do bfcache no DevTools e, este ano, planejamos aprimorar as ferramentas com uma nova auditoria do Lighthouse que realiza um teste semelhante e uma API para medir isso em campo.
Embora tenhamos incluído o bfcache na seção de CLS, como vimos os maiores ganhos até agora, ele geralmente também melhora outras Core Web Vitals. Ele faz parte das diversas navegações instantâneas disponíveis que melhoram drasticamente a navegação nas páginas.
Evite animações/transições que usam propriedades CSS que induzem layout
Outra fonte comum de trocas de layout é quando os elementos são animados. Por exemplo, banners de cookies ou outros banners de notificação que deslizam da parte superior ou inferior para dentro costumam contribuir para a CLS. Isso é particularmente problemático quando esses banners empurram outros conteúdos para fora do caminho, mas mesmo quando isso não acontece, animá-los ainda pode afetar o CLS.
Embora os dados do Arquivo HTTP não possam conectar animações a mudanças de layout de forma conclusiva, os dados mostram que as páginas que animam qualquer propriedade CSS que pode afetar o layout têm 15% menos probabilidade de ter uma "boa" CLS do que as páginas em geral. Algumas propriedades estão associadas a pior CLS do que outras. Por exemplo, páginas que animam larguras de margin
ou border
têm "baixa" CLS quase o dobro da taxa que as páginas em geral são avaliadas como ruins.
Talvez isso não seja surpreendente, porque sempre que você fizer a transição ou animar qualquer propriedade CSS que induza um layout, isso vai resultar em mudanças de layout e, se elas não acontecerem dentro de 500 milissegundos após uma interação do usuário, elas vão afetar a CLS.
O que pode surpreender alguns desenvolvedores é que isso é verdade mesmo nos casos em que o elemento é tirado do fluxo normal de documentos. Por exemplo, elementos posicionados de forma absoluta que animam top
ou left
causarão mudanças de layout, mesmo que eles não estejam movimentando outros conteúdos. No entanto, se, em vez de animar top
ou left
, você animar transform:translateX()
ou transform:translateY()
, o navegador não vai atualizar o layout da página e, portanto, não produzirá nenhuma mudança de layout.
Priorizar a animação de propriedades CSS que podem ser atualizadas no thread de compositor do navegador tem sido uma prática recomendada de desempenho porque move esse trabalho para a GPU e para fora da linha de execução principal. Além de ser uma prática recomendada de desempenho geral, ela também pode ajudar a melhorar a CLS.
Como regra geral, nunca anime ou faça a transição de propriedades CSS que exijam que o navegador atualize o layout da página, a menos que isso seja feito em resposta a um toque do usuário ou ao pressionamento de uma tecla (não hover
). Sempre que possível, prefira transições e animações usando a propriedade transform
do CSS.
A auditoria do Lighthouse Evitar animações não compostas avisará quando uma página animar propriedades CSS potencialmente lentas.
First Input Delay (FID)
Nosso último conjunto de recomendações é para a First Input Delay (FID), que é uma medida da capacidade de resposta de uma página às interações do usuário. Embora a maioria dos sites da Web tenha uma boa pontuação na FID, já documentamos as deficiências dessa métrica no passado, e acreditamos que ainda há muitas oportunidades para que os sites melhorem a capacidade geral de resposta às interações do usuário.
Nossa nova métrica Interação com a próxima pintura (INP, na sigla em inglês) é uma possível sucessora da FID, e todas as recomendações abaixo se aplicam igualmente bem a ambas. Considerando que os sites têm um desempenho pior no INP do que no FID, principalmente em dispositivos móveis, recomendamos que os desenvolvedores considerem seriamente essas recomendações de capacidade de resposta, apesar de terem uma "boa" FID.
Evitar ou dividir tarefas longas
Tarefas são qualquer trabalho discreto realizado pelo navegador. As tarefas incluem renderização, layout, análise, compilação e execução de scripts. Quando as tarefas se tornam tarefas longas, ou seja, 50 milissegundos ou mais, elas impedem que a linha de execução principal responda rapidamente às entradas do usuário.
De acordo com o Web Almanac, há muitas evidências (em inglês) que sugerem que os desenvolvedores podem fazer mais para evitar ou dividir tarefas longas. Embora dividir tarefas longas possa não ser tão simples quanto outras recomendações neste artigo, isso exige menos esforço do que outras técnicas não oferecidas neste artigo.
É necessário sempre fazer o mínimo de trabalho possível em JavaScript, mas você pode ajudar bastante a linha de execução principal dividindo tarefas longas em tarefas menores. Você pode fazer isso rendendo à linha de execução principal com frequência para que as atualizações de renderização e outras interações do usuário ocorram mais rapidamente.
Outra opção é considerar o uso de APIs como isInputPending
e API Scheduler. isInputPending
é uma função que retorna um valor booleano que indica se uma entrada do usuário está pendente. Se ele retornar true
, você poderá acessar a linha de execução principal para que ela possa processar a entrada pendente do usuário.
A API Scheduler é uma abordagem mais avançada, que permite agendar trabalhos com base em um sistema de prioridades que levam em consideração se o trabalho que está sendo feito é visível para o usuário ou em segundo plano.
Ao dividir tarefas longas, você dá ao navegador mais oportunidades de se encaixar em trabalhos essenciais visíveis ao usuário, como lidar com interações e as atualizações de renderização resultantes.
Evitar JavaScript desnecessário
Não há dúvida disso: os sites estão enviando mais JavaScript do que nunca, e a tendência parece que não vai mudar tão cedo. Quando você envia muito JavaScript, está criando um ambiente em que as tarefas competem pela atenção da linha de execução principal. Isso pode definitivamente afetar a capacidade de resposta do seu site, especialmente durante esse período crucial de inicialização.
No entanto, esse não é um problema insolúvel. Você tem algumas opções:
- Use a ferramenta de cobertura no Chrome DevTools para encontrar código não utilizado nos recursos do seu site. Ao reduzir o tamanho dos recursos necessários durante a inicialização, você garante que seu site gaste menos tempo analisando e compilando códigos, o que resulta em uma experiência inicial mais tranquila para o usuário.
- Às vezes, o código não utilizado encontrado com a ferramenta de cobertura é marcado como "não utilizado" porque ele não foi executado durante a inicialização, mas ainda é necessário para algumas funcionalidades no futuro. Esse é o código que você pode mover para um pacote separado por meio da divisão de código.
- Se você estiver usando um gerenciador de tags, verifique com frequência suas tags para garantir que elas estejam otimizadas ou mesmo se ainda estiverem sendo usadas. Tags mais antigas com código não utilizado podem ser apagadas para tornar o JavaScript do Gerenciador de tags menor e mais eficiente.
Evitar grandes atualizações de renderização
O JavaScript não é o único fator que pode afetar a capacidade de resposta do seu site. A renderização pode ser um tipo de trabalho caro por si só. E, quando grandes atualizações de renderização ocorrem, elas podem interferir na capacidade do site de responder às entradas do usuário.
Otimizar o trabalho de renderização não é um processo simples e muitas vezes depende do que você está tentando alcançar. Mesmo assim, há algumas medidas que você pode tomar para garantir que as atualizações de renderização sejam razoáveis e não se transformem em tarefas longas:
- Evite usar
requestAnimationFrame()
para fazer trabalhos não visuais. As chamadasrequestAnimationFrame()
são processadas durante a fase de renderização do loop de eventos e, quando muito trabalho é feito durante essa etapa, as atualizações de renderização podem ser atrasadas. É essencial que qualquer trabalho realizado com orequestAnimationFrame()
seja reservado estritamente para tarefas que envolvam atualizações de renderização. - Mantenha o tamanho do seu DOM pequeno. O tamanho do DOM e a intensidade do trabalho de layout estão correlacionados. Quando o renderizador precisa atualizar o layout para um DOM muito grande, o trabalho necessário para recalcular o layout pode aumentar significativamente.
- Use a contenção de CSS. A contenção do CSS depende da propriedade CSS
contain
, que fornece instruções ao navegador sobre como fazer o trabalho de layout para o contêiner em que a propriedadecontain
está definida, incluindo até mesmo isolar o escopo do layout e a renderização para uma raiz específica no DOM. Nem sempre é um processo fácil, mas ao isolar áreas que contenham layouts complexos, você pode evitar fazer trabalho de layout e renderização que não sejam necessários para elas.
Conclusão
Melhorar o desempenho da página pode parecer uma tarefa assustadora, especialmente porque há muitas orientações por toda a Web a serem consideradas. No entanto, ao se concentrar nessas recomendações, você pode abordar o problema com foco e propósito e, se tudo der certo, melhorar as Core Web Vitals do seu site.
Embora as recomendações listadas aqui não sejam completas, acreditamos, com base em uma análise cuidadosa do estado da Web, que essas recomendações são as maneiras mais eficazes de os sites melhorarem o desempenho das Core Web Vitals em 2023.
Se você quiser ir além das recomendações listadas aqui, confira estes guias de otimização para mais informações:
Desejamos um novo ano e uma Web mais rápida para todos! Que seus sites sejam rápidos para os usuários nos momentos mais importantes.
Foto de Devin Avery