Carregamentos de página mais rápidos usando o tempo de reflexão do servidor com dicas iniciais

Descubra como seu servidor pode enviar dicas para o navegador sobre sub-recursos críticos.

Kenji Baheux
Kenji Baheux
Barry Pollard
Barry Pollard

O que são as primeiras dicas?

Os sites se tornaram mais sofisticados com o tempo. Dessa forma, não é incomum que um servidor precise realizar um trabalho não trivial (por exemplo, acesso a bancos de dados ou CDNs que acessam o servidor de origem) para produzir o HTML da página solicitada. Infelizmente, esse "tempo de processamento do servidor" resulta em latência extra antes que o navegador possa começar a renderizar a página. De fato, a conexão fica inativa pelo tempo que o servidor leva para preparar a resposta.

Imagem mostrando o intervalo de tempo de reflexão do servidor de 200 ms entre o carregamento da página e o carregamento de outros recursos.
Sem dicas antecipadas: tudo é bloqueado no servidor que determina como responder pelo recurso principal.

As dicas iniciais são um código de status HTTP (103 Early Hints) usado para enviar uma resposta HTTP preliminar antes de uma resposta final. Isso permite que um servidor envie dicas ao navegador sobre sub-recursos críticos (por exemplo, folhas de estilo para a página, JavaScript crítico) ou origens que provavelmente serão usadas pela página enquanto o servidor está ocupado gerando o recurso principal. O navegador pode usar essas dicas para aquecer as conexões e solicitar subrecursos enquanto aguarda o recurso principal. Em outras palavras, as dicas antecipadas ajudam o navegador a aproveitar esse "tempo de reflexão do servidor" fazendo um trabalho antecipado, acelerando o carregamento da página.

Imagem mostrando como as dicas antecipadas permitem que a página envie uma resposta parcial.
Com dicas antecipadas: o servidor pode exibir uma resposta parcial com dicas de recursos enquanto determina a resposta final

Em alguns casos, a melhoria de desempenho da Largest Contentful Paint pode passar de várias centenas de milissegundos, como observado pela Shopify e pela Cloudflare, e até um segundo mais rápido, como mostrado nesta comparação antes e depois:

Comparação de dois sites.
Comparação antes/depois de Early Hints em um site de teste feito com o WebPageTest (Moto G4 - DSL)

Como usar os Early Hints

A primeira etapa para aproveitar os Early Hints é identificar as principais páginas de destino, ou seja, as páginas em que os usuários geralmente começam quando visitam seu site. Pode ser a página inicial ou as páginas de informações de produtos populares se você tiver muitos usuários vindos de outros sites. Esses pontos de entrada são mais importantes do que as outras páginas porque a utilidade das dicas iniciais diminui à medida que o usuário navega pelo site (ou seja, é mais provável que o navegador tenha todos os sub-recursos necessários na segunda ou terceira navegação subsequente). Também é sempre uma boa ideia causar uma ótima primeira impressão.

Agora que você tem essa lista priorizada de páginas de destino, a próxima etapa é identificar quais origens ou subrecursos seriam bons candidatos para dicas preconnect ou preload. Normalmente, são origens e subrecursos que contribuem mais para as principais métricas do usuário, como Largest Contentful Paint ou First Contentful Paint. Mais especificamente, procure subrecursos que bloqueiam a renderização, como JavaScript síncrono, folhas de estilo ou até mesmo fontes da Web. Da mesma forma, procure origens que hospedam subrecursos que contribuem muito para as principais métricas do usuário.

Além disso, se os recursos principais já estiverem usando preconnect ou preload, considere essas origens ou recursos como candidatos para as dicas antecipadas. Saiba como otimizar o LCP para mais detalhes. No entanto, copiar de forma simples as diretivas preconnect e preload do HTML para as dicas iniciais pode não ser o ideal.

Ao usar esses recursos no HTML, normalmente você quer preconnect ou preload recursos que o Preload Scanner não vai descobrir no HTML, como fontes ou imagens de plano de fundo que seriam descobertas mais tarde. Para as dicas iniciais, você não tem o HTML, portanto, pode querer preconnect para domínios críticos ou preload recursos essenciais que talvez poderiam ser descobertos no início do HTML, por exemplo, pré-carregando main.css ou app.js. Além disso, nem todos os navegadores oferecem suporte a preload para dicas iniciais. Consulte Suporte do navegador.

A segunda etapa consiste em minimizar o risco de usar os Early Hints em recursos ou origens que podem estar obsoletos ou não são mais usados pelo recurso principal. Por exemplo, recursos que são atualizados e versionados com frequência (por exemplo, example.com/css/main.fa231e9c.css) podem não ser a melhor escolha. Essa preocupação não é específica para os Early Hints, mas se aplica a qualquer preload ou preconnect, onde quer que eles estejam. Esse é o tipo de detalhe que é melhor tratado com automação ou modelos. Por exemplo, um processo manual tem mais probabilidade de gerar URLs de hash ou de versão incompatíveis entre preload e a tag HTML real que usa o recurso.

Por exemplo, considere o seguinte fluxo:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]

O servidor prevê que main.abcd100.css será necessário e sugere o pré-carregamento usando as Dicas antecipadas:

103 Early Hints
Link: </main.abcd100.css>; rel=preload; as=style
[...]

Alguns instantes depois, a página da Web, incluindo o CSS vinculado, é exibida. Infelizmente, este recurso de CSS é atualizado com frequência, e o recurso principal já está cinco versões à frente (abcd105) do recurso de CSS previsto (abcd100).

200 OK
[...]
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.abcd105.css">

Em geral, procure recursos e origens que sejam bastante estáveis e, em grande parte, independentes do resultado do recurso principal. Se necessário, divida seus principais recursos em dois: uma parte estável projetada para ser usada com os Early Hints e uma parte mais dinâmica que será buscada depois que o recurso principal for recebido pelo navegador:

<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">

Por fim, no lado do servidor, procure solicitações de recursos principais enviadas por navegadores conhecidos por oferecer suporte a Early Hints e responda imediatamente com 103 Early Hints. Na resposta 103, inclua as dicas relevantes de pré-conexão e pré-carregamento. Quando o recurso principal estiver pronto, dê a resposta habitual (por exemplo, 200 OK se for bem-sucedido). Para compatibilidade com versões anteriores, é recomendável incluir também cabeçalhos HTTP Link na resposta final, talvez até aumentando com recursos críticos que se tornaram evidentes como parte da geração do recurso principal (por exemplo, a parte dinâmica de um recurso principal se você seguiu a sugestão "dividir em dois"). Confira como isso ficaria:

GET /main.html
Host: example.com
User-Agent: [....] Chrome/103.0.0.0 [...]
103 Early Hints
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script

Alguns instantes:

200 OK
Content-Length: 7531
Content-Type: text/html; charset=UTF-8
Content-encoding: br
Link: <https://fonts.google.com>; rel=preconnect
Link: </main.css>; rel=preload; as=style
Link: </common.js>; rel=preload; as=script
Link: </experimental.3eab3290.css>; rel=preload; as=style
<HTML>
<head>
   <title>Example</title>
   <link rel="stylesheet" href="/main.css">
   <link rel="stylesheet" href="/experimental.3eab3290.css">
   <script src="/common.js"></script>
   <link rel="preconnect" href="https://fonts.googleapis.com">

Suporte ao navegador

Embora 103 Early Hints tenha suporte em todos os principais navegadores, as diretivas que podem ser enviadas em um Early Hint variam de acordo com o navegador:

Suporte para pré-conexão:

Compatibilidade com navegadores

  • Chrome: 103.
  • Edge: 103.
  • Firefox: 120.
  • Safari: 17.

Suporte para pré-carregar:

Compatibilidade com navegadores

  • Chrome: 103.
  • Edge: 103.
  • Firefox: 123.
  • Safari: não é compatível.

O Chrome DevTools também tem suporte a 103 Early Hints, e os cabeçalhos Link podem ser vistos nos recursos do documento:

Painel de rede mostrando cabeçalhos de dicas iniciais
Os cabeçalhos Early Hints Link são mostrados no Chrome DevTools.

Para usar os recursos de dicas antecipadas, Disable cache não pode ser marcada no DevTools, porque as dicas antecipadas usam o cache do navegador. Para recursos pré-carregados, o iniciador vai aparecer como early-hints e o tamanho como (Disk cache):

Painel de rede mostrando iniciadores de Early Hints
Os recursos com dicas antecipadas têm um iniciador early-hints e são carregados do armazenamento em cache do disco.

Isso também requer um certificado confiável para testes HTTPS.

O Firefox (a partir da versão v126) não tem suporte explícito ao 103 Early Hints no DevTools, mas os recursos carregados usando as Early Hints não mostram as informações do cabeçalho HTTP, que é um indicador de que eles foram carregados usando as Early Hints.

Suporte a servidor

Confira um resumo rápido do nível de suporte para os Early Hints entre os softwares de servidor HTTP de software de código aberto mais conhecidos:

Ativar os Early Hints de maneira mais fácil

Se você estiver usando uma das CDNs ou plataformas a seguir, talvez não seja necessário implementar os Early Hints manualmente. Consulte a documentação on-line do provedor de solução para saber se ela oferece suporte a Early Hints ou consulte a lista não exaustiva aqui:

Como evitar problemas com clientes que não têm suporte a Early Hints

Respostas HTTP informativas de 100 pessoas fazem parte do padrão HTTP, mas alguns clientes ou bots mais antigos podem ter dificuldades com elas, porque, antes do lançamento das 103 dicas iniciais, elas raramente eram usadas para navegação geral na Web.

A emissão de apenas 103 dicas antecipadas em resposta a clientes que enviam um cabeçalho de solicitação HTTP sec-fetch-mode: navigate precisa garantir que essas dicas sejam enviadas apenas para clientes mais recentes que entendam que precisam aguardar a resposta subsequente. Além disso, como os Early Hints têm suporte apenas para solicitações de navegação (consulte as limitações atuais), isso tem o benefício adicional de evitar o envio desnecessário em outras solicitações.

Além disso, é recomendável enviar os Early Hints apenas por conexões HTTP/2 ou HTTP/3, e a maioria dos navegadores só os aceita por esses protocolos.

Padrão avançado

Se você já aplicou os Early Hints às suas principais páginas de destino e está em busca de mais oportunidades, talvez o seguinte padrão avançado seja interessante.

Para visitantes que estão na nª solicitação de página como parte de uma jornada de usuário típica, é recomendável adaptar a resposta dos Early Hints para conteúdo mais baixo e profundo na página, ou seja, usar os Early Hints em recursos de prioridade mais baixa. Isso pode parecer contra-intuitivo, já que recomendamos focar em subrecursos ou origens de alta prioridade que bloqueiam a renderização. No entanto, quando um visitante navega por um tempo, é muito provável que o navegador já tenha todos os recursos essenciais. A partir daí, pode ser sensato mudar sua atenção para recursos de menor prioridade. Por exemplo, isso pode significar usar as dicas iniciais para carregar imagens de produtos ou JS/CSS adicional necessário apenas para interações menos comuns do usuário.

Limitações atuais

Estas são as limitações das dicas antecipadas implementadas no Chrome:

  • Disponível apenas para solicitações de navegação (ou seja, o recurso principal do documento de nível superior).
  • Somente preconnect e preload são aceitos. prefetch não é aceito.
  • Os Early Hints seguidos por um redirecionamento entre origens na resposta final fazem com que o Chrome perca os recursos e as conexões que ele recebeu usando os Early Hints.
  • Recursos pré-carregados com as dicas iniciais são armazenados no cache HTTP e recuperados de lá pela página mais tarde. Portanto, apenas recursos armazenáveis em cache podem ser pré-carregados usando os Early Hints, ou o recurso será buscado duas vezes (uma vez pelos Early Hints e outra pelo documento). No Chrome, o cache HTTP é desativado para certificados HTTPS não confiáveis, mesmo que você continue carregando a página.
  • O pré-carregamento de imagens responsivas (usando imagesrcset, imagesizes ou media) não é compatível com cabeçalhos HTTP <link>, porque a viewport não é definida até que o documento seja criado. Isso significa que as dicas antecipadas 103 não podem ser usadas para pré-carregar imagens responsivas e podem carregar a imagem incorreta quando usadas para isso. Siga esta discussão sobre propostas para lidar melhor com isso.

Outros navegadores têm limitações semelhantes e, como observado anteriormente, alguns restringem ainda mais as 103 dicas iniciais apenas a preconnect.

A seguir

Dependendo do interesse da comunidade, podemos aumentar a implementação das Dicas antecipadas com os seguintes recursos:

  • As dicas antecipadas para recursos não cacháveis usam o cache de memória em vez do cache HTTP.
  • Dicas iniciais enviadas em solicitações de sub-recursos.
  • As dicas antecipadas são enviadas em solicitações de recursos principais do iframe.
  • Suporte para pré-carregamento em dicas antecipadas.

Queremos saber sua opinião sobre quais aspectos priorizar e como melhorar ainda mais os Early Hints.

Relação com o H2/push

Se você conhece o recurso HTTP2/Push descontinuado, pode se perguntar qual é a diferença entre as dicas iniciais. Embora os Early Hints exijam uma ida e volta para que o navegador comece a buscar subrecursos críticos, com o HTTP2/Push, o servidor pode começar a enviar subrecursos com a resposta. Embora isso pareça incrível, resultou em uma desvantagem estrutural importante: com o HTTP2/Push, era extremamente difícil evitar o envio de subrecursos que o navegador já tinha. Esse efeito de "forçar demais" resultou em um uso menos eficiente da largura de banda da rede, o que atrapalhou significativamente os benefícios de desempenho. No geral, os dados do Chrome mostraram que o HTTP2/Push era, na verdade, um fator negativo para o desempenho na Web.

Por outro lado, os Early Hints têm um desempenho melhor na prática porque combinam a capacidade de enviar uma resposta preliminar com dicas que deixam o navegador responsável por buscar ou se conectar ao que ele realmente precisa. Embora as dicas iniciais não abordem todos os casos de uso que o HTTP2/Push poderia abordar em teoria, acreditamos que as dicas iniciais são uma solução mais prática para acelerar as navegações.

Imagem de miniatura de Pierre Bamin.