Otimizar o carregamento de recursos com a API Fetch Preview

Addy Osmani
Addy Osmani
Leena Sohoni
Leena Sohoni
Patrick Meenan
Patrick Meenan

Compatibilidade com navegadores

  • 102
  • 102
  • x
  • 17,2

Origem

Quando um navegador analisa uma página da Web e começa a descobrir e fazer o download de recursos, como imagens, scripts ou CSS, ele atribui um priority de busca para que possa fazer o download na ordem ideal. A prioridade de um recurso geralmente depende do que ele é e de onde ele está no documento. Por exemplo, as imagens na janela de visualização podem ter uma prioridade High, e a prioridade do CSS bloqueador de renderização com carregamento antecipado usando <link>s no <head> pode ser Very High. A atribuição de prioridade automática geralmente funciona bem, mas há casos de uso em que a ordem atribuída não é ideal.

Esta página aborda a API Fetch Preview e o atributo HTML fetchpriority, que ajudam a otimizar as Core Web Vitals, permitindo indicar a prioridade relativa de um recurso (high ou low).

Resumo

Confira algumas das principais vantagens em que a prioridade de busca pode ajudar:

  • Otimização da prioridade da imagem LCP especificando fetchpriority="high" no elemento de imagem, fazendo com que a LCP aconteça mais cedo.
  • Aumentar a prioridade dos scripts async, usando semântica melhor do que a hacking mais comum (inserir um <link rel="preload"> para o script async).
  • Diminuir a prioridade dos scripts de corpo atrasado para sequenciar melhor as imagens.
Uma visualização em tira de filme comparando dois testes da página inicial do Google Voos. Na parte de baixo,
    a prioridade de busca é usada para aumentar a prioridade da imagem principal, resultando em
    uma redução de 0,7 segundo na LCP.
A prioridade de busca melhora a Maior exibição de conteúdo de 2,6 s para 1,9 s em um teste do Google Voos.

Historicamente, os desenvolvedores tiveram influência limitada sobre a prioridade de recursos usando pré-carregamento e pré-conexão. O pré-carregamento permite que você informe ao navegador sobre os recursos essenciais que quer carregar antecipadamente antes que o navegador os descubra naturalmente. Isso é especialmente útil para recursos mais difíceis de descobrir, como fontes incluídas em folhas de estilo, imagens de plano de fundo ou recursos carregados de um script. A pré-conexão ajuda a aquecer conexões com servidores de origem cruzada e pode ajudar a melhorar métricas como o Tempo até o primeiro byte. Ela é útil quando você conhece a origem, mas não necessariamente o URL exato de um recurso que será necessário.

A prioridade de busca complementa estas Dicas de recursos. É um indicador baseado em marcação, disponível pelo atributo fetchpriority, que os desenvolvedores podem usar para indicar a prioridade relativa de um recurso específico. Também é possível usar essas dicas em JavaScript e a API Fetch com a propriedade priority para influenciar a prioridade das buscas de recursos feitas para os dados. A prioridade de busca também pode complementar o pré-carregamento. Pegue uma imagem de Maior exibição de conteúdo, que, quando pré-carregada, ainda terá uma prioridade baixa. Se ela for recusada por outros recursos iniciais de baixa prioridade, o uso da prioridade de busca poderá ajudar a identificar a rapidez com que a imagem é carregada.

Prioridade do recurso

A sequência de download de recursos depende da prioridade atribuída do navegador para cada recurso na página. Os fatores que podem afetar a lógica de computação de prioridade incluem os seguintes:

  • O tipo de recurso, como CSS, fontes, scripts, imagens e recursos de terceiros.
  • O local ou a ordem em que o documento referencia os recursos.
  • A dica de recurso preload, que ajuda o navegador a descobrir um recurso mais rapidamente e carregá-lo mais cedo.
  • Mudanças no cálculo de prioridade para scripts async ou defer.

A tabela a seguir mostra como o Chrome prioriza e sequencia a maioria dos recursos:

  Carregar na fase de bloqueio de layout Carregar um por vez na fase de bloqueio de layout
Prioridade de
Blink
VeryHigh Alta Média Baixo VeryLow
DevTools
Prioridade
Mais alta Alta Média Baixo Menor
Recurso principal
CSS (adiantado**) CSS (atrasado**) CSS (incompatibilidade de mídia***)
Script (anterior** ou não ao leitor de pré-carregamento) Script (atrasado**) Script (assíncrono)
Fonte Fonte (rel=preload)
Importar
Imagem (na janela de visualização) Imagem (cinco primeiras imagens > 10.000px2) Imagem
Mídia (vídeo/áudio)
Pré-busca
XSL
XHR (sincronização) XHR/busca* (assíncrono)

O navegador faz o download de recursos com a mesma prioridade calculada na ordem em que são descobertos. É possível verificar a prioridade atribuída a diferentes recursos ao carregar uma página na guia Rede das Ferramentas do Chrome Dev. Inclua a coluna "Prioridade" clicando com o botão direito do mouse nos cabeçalhos da tabela.

Uma captura de tela dos recursos listados na guia de rede do DevTools do Chrome. As colunas são lidas, da esquerda para a direita: nome, status, tipo, iniciador, tamanho, tempo e prioridade.
Prioridade para o recurso type = "font" na página de detalhes de notícias da BBC
Uma captura de tela dos recursos listados na guia de rede do DevTools do Chrome. As colunas são lidas, da esquerda para a direita: nome, status, tipo, iniciador, tamanho, tempo e prioridade.
Prioridade para o tipo de recurso = "script" na página de detalhes de notícias da BBC.

Quando as prioridades mudam, é possível ver a prioridade inicial e final na configuração Linhas de solicitação grande ou em uma dica.

Uma captura de tela dos recursos listados na guia de rede do DevTools do Chrome. A configuração &quot;Linhas de solicitação grande&quot; é marcada, e a coluna &quot;Prioridade&quot; mostra a primeira imagem com a prioridade &quot;Alta&quot; e outra com a prioridade inicial &quot;Média&quot; abaixo. O mesmo aparece na dica.
Mudanças de prioridade no DevTools.

Quando você pode precisar da prioridade de busca?

Agora que você entende a lógica de priorização do navegador, é possível ajustar a ordem de download da página para otimizar o desempenho e as Core Web Vitals. Veja alguns exemplos do que é possível mudar sem usar a prioridade de busca:

  • Coloque as tags de recursos, como <script> e <link>, na ordem em que você quer que o navegador faça o download delas.
  • Use a dica de recurso preload para fazer o download dos recursos necessários com antecedência, especialmente aqueles mais difíceis de serem descobertos pelo navegador.
  • Use async ou defer para fazer o download de scripts sem bloquear outros recursos.
  • Carregue lentamente o conteúdo abaixo da dobra para que o navegador possa usar a largura de banda disponível para recursos mais importantes acima da dobra.

Aqui estão alguns casos mais complexos em que a prioridade de busca pode ajudar você a conseguir a ordem de prioridade de recursos necessária:

  • Você tem várias imagens acima da dobra, mas nem todas têm a mesma prioridade. Por exemplo, em um carrossel de imagens, apenas a primeira imagem visível precisa de uma prioridade mais alta.
  • As imagens principais na janela de visualização geralmente começam com uma prioridade Low ou Medium. Depois que o layout é concluído, o Chrome descobre que eles estão na janela de visualização e aumenta a prioridade deles. Isso geralmente adiciona um atraso significativo ao carregamento das imagens. Fornecer a prioridade de busca na marcação permite que a imagem comece com prioridade "Alta" e comece a carregar muito mais cedo.

    O pré-carregamento ainda é necessário para a descoberta antecipada de imagens de LCP incluídas como planos de fundo em CSS. Para aumentar a prioridade das imagens de plano de fundo, inclua fetchpriority='high' no pré-carregamento.
  • Declarar scripts como async ou defer instrui o navegador a carregá-los de forma assíncrona. No entanto, conforme mostrado na tabela de prioridade, esses scripts também recebem uma prioridade "Baixa". É possível aumentar a prioridade e garantir o download assíncrono, principalmente de scripts essenciais para a experiência do usuário.
  • Se você usar a API JavaScript fetch() para buscar recursos ou dados de forma assíncrona, o navegador vai atribuir a ele a prioridade High. Talvez você queira que algumas das suas buscas sejam executadas com menor prioridade, especialmente se você estiver misturando chamadas de API em segundo plano com chamadas de API que respondem à entrada do usuário. Marque as chamadas de API em segundo plano como prioridade Low e as chamadas de API interativas como prioridade High.
  • O navegador atribui CSS e fontes um High" priority, mas alguns desses recursos podem ser mais importantes que outros. Use a prioridade de busca para diminuir a prioridade de recursos não críticos.

O atributo fetchpriority

Use o atributo HTML fetchpriority para especificar a prioridade de download de tipos de recursos, como CSS, fontes, scripts e imagens, quando o download for feito usando as tags link, img ou script. Pode ter os seguintes valores:

  • high: o recurso tem alta prioridade, e você quer que o navegador o priorize, desde que a própria heurística não impeça isso de acontecer.
  • low: o recurso tem baixa prioridade, e você quer que o navegador diminua a prioridade dele, se a heurística permitir.
  • auto: o valor padrão, que permite ao navegador escolher a prioridade adequada.

Confira alguns exemplos de como usar o atributo fetchpriority na marcação, bem como a propriedade priority equivalente ao script.

<!-- We don't want a high priority for this above-the-fold image -->
<img src="/images/in_viewport_but_not_important.svg" fetchpriority="low" alt="I'm an unimportant image!">

<!-- We want to initiate an early fetch for a resource, but also deprioritize it -->
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">

<script>
  fetch('https://example.com/', {priority: 'low'})
  .then(data => {
    // Trigger a low priority fetch
  });
</script>

Efeitos da prioridade do navegador e da fetchpriority

É possível aplicar o atributo fetchpriority a diferentes recursos, conforme mostrado na tabela a seguir, para aumentar ou reduzir a prioridade calculada. O fetchpriority="auto" (◉) em cada linha marca a prioridade padrão para esse tipo de recurso.

  Carregar na fase de bloqueio de layout Carregar um de cada vez na fase de bloqueio de layout
Prioridade de
Blink
VeryHigh Alta Média Baixo VeryLow
DevTools
Prioridade
Mais alta Alta Média Baixo Menor
Recurso principal
CSS (adiantado**) ⬆◉
CSS (atrasado**)
CSS (incompatibilidade de mídia***) ⬆*** ◉⬇
Script (anterior** ou não ao leitor de pré-carregamento) ⬆◉
Script (atrasado**)
Script (assíncrono/adiar) ◉⬇
Fonte
Fonte (rel=preload) ⬆◉
Importar
Imagem (na janela de visualização - após o layout) ⬆◉
Imagem (cinco primeiras imagens > 10.000px2)
Imagem ◉⬇
Mídia (vídeo/áudio)
XHR (sincronização) - descontinuado
XHR/busca* (assíncrono) ⬆◉
Pré-busca
XSL

fetchpriority define a prioridade relativa, o que significa que ele aumenta ou diminui a prioridade padrão por um valor adequado, em vez de definir explicitamente a prioridade como High ou Low. Isso geralmente resulta em prioridade High ou Low, mas nem sempre. Por exemplo, o CSS crítico com fetchpriority="high" mantém a prioridade "MuitoAlta"/"Mais alta", e o uso de fetchpriority="low" nesses elementos mantém a prioridade "Alta". Nenhum desses casos envolve a definição explícita da prioridade como High ou Low.

Casos de uso

Use o atributo fetchpriority quando quiser dar ao navegador uma dica extra sobre com qual prioridade buscar um recurso.

Aumente a prioridade da imagem LCP

É possível especificar fetchpriority="high" para aumentar a prioridade da LCP ou de outras imagens críticas.

<img src="lcp-image.jpg" fetchpriority="high">

A comparação a seguir mostra a página do Google Voos com uma imagem de plano de fundo da LCP carregada com e sem prioridade de busca. Com a prioridade definida como alta, a LCP melhorou de 2,6s para 1,9s.

Um experimento realizado com os workers do Cloudflare para reescrever a página do Google Voos usando a prioridade de busca.

Use fetchpriority="low" para diminuir a prioridade de imagens acima da dobra que não são imediatamente importantes, por exemplo, em um carrossel.

<ul class="carousel">
  <img src="img/carousel-1.jpg" fetchpriority="high">
  <img src="img/carousel-2.jpg" fetchpriority="low">
  <img src="img/carousel-3.jpg" fetchpriority="low">
  <img src="img/carousel-4.jpg" fetchpriority="low">
</ul>

Em um experimento anterior com o app Oodle (link em inglês), usamos esse recurso para diminuir a prioridade das imagens que não aparecem no carregamento. Isso diminuiu o tempo de carregamento da página em dois segundos.

Uma comparação lado a lado da prioridade de busca usada no carrossel de imagens do app Oodle. À esquerda, o navegador define prioridades padrão para imagens de carrossel, mas faz o download e pinta essas imagens cerca de dois segundos mais devagar que o exemplo à direita, que define uma prioridade mais alta apenas na primeira imagem do carrossel.
Usar a prioridade alta apenas para a primeira imagem de carrossel permite que a página carregue mais rapidamente.

Diminuir a prioridade de recursos pré-carregados

Para impedir que recursos pré-carregados concorram com outros recursos críticos, você pode reduzir a prioridade deles. Use essa técnica com imagens, scripts e CSS.

<!-- Lower priority only for non-critical preloaded scripts -->
<link rel="preload" as="script" href="critical-script.js">
<link rel="preload" href="/js/script.js" as="script" fetchpriority="low">

<!-- Preload CSS without blocking other resources -->
<link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">

Redefinir a prioridade de scripts

Os scripts que sua página precisa ser interativa precisam ser carregados rapidamente, mas não podem bloquear outros recursos. Você pode marcar esses itens como async com prioridade alta.

<script src="async_but_important.js" async fetchpriority="high"></script>

Não é possível marcar um script como async se ele depender de estados específicos do DOM. No entanto, se elas forem executadas mais tarde na página, você poderá carregá-las com prioridade mais baixa:

<script src="blocking_but_unimportant.js" fetchpriority="low"></script>

Diminuir a prioridade para buscas de dados não críticos

O navegador executa fetch com prioridade alta. Se você tiver várias buscas que podem ser disparadas simultaneamente, use a prioridade padrão alta para as buscas de dados mais importantes e diminua a prioridade dos dados menos críticos.

// Important validation data (high by default)
let authenticate = await fetch('/user');

// Less important content data (suggested low)
let suggestedContent = await fetch('/content/suggested', {priority: 'low'});

Buscar notas de implementação de prioridade

Veja alguns pontos a serem considerados ao usar a prioridade de busca:

  • O atributo fetchpriority é uma dica, não uma diretiva. O navegador tenta respeitar a preferência do desenvolvedor, mas também pode aplicar as preferências de prioridade de recursos para resolver conflitos.
  • Não confunda a prioridade de busca com pré-carregamento:

    • O pré-carregamento é uma busca obrigatória, não uma dica.
    • O pré-carregamento permite que o navegador descubra um recurso com antecedência, mas ainda o busca com a prioridade padrão. Enquanto isso, a prioridade de busca não ajuda na detecção, mas permite aumentar ou diminuir a prioridade de busca.
    • É mais fácil observar e medir os efeitos de um pré-carregamento do que os de uma mudança de prioridade.

    A prioridade de busca pode complementar os pré-carregamentos aumentando a granularidade da priorização. Se você já especificou um pré-carregamento como um dos primeiros itens na <head> para uma imagem LCP, é possível que uma prioridade de busca high não melhore a LCP significativamente. No entanto, se o pré-carregamento ocorrer após o carregamento de outros recursos, uma prioridade de busca high poderá melhorar ainda mais a LCP. Se uma imagem crítica for uma imagem de plano de fundo CSS, pré-carregue-a com fetchpriority = "high".

  • As melhorias no tempo de carregamento da priorização são mais relevantes em ambientes em que mais recursos competem pela largura de banda da rede disponível. Isso é comum em conexões HTTP/1.x em que os downloads paralelos não são possíveis ou em conexões HTTP/2 com baixa largura de banda. Nesses casos, a priorização pode ajudar a resolver gargalos.

  • As CDNs não implementam a priorização HTTP/2 de maneira uniforme. Mesmo que o navegador comunique a prioridade da prioridade de busca, a CDN pode não atribuir uma nova prioridade aos recursos na ordem especificada. Isso dificulta os testes da prioridade de busca. As prioridades são aplicadas internamente no navegador e com protocolos compatíveis com priorização (HTTP/2 e HTTP/3). Ainda vale a pena usar a prioridade de busca apenas para a priorização interna do navegador, independente do suporte a CDN ou origem, porque as prioridades geralmente mudam quando o navegador solicita recursos. Por exemplo, recursos de baixa prioridade, como imagens, geralmente são impedidos de serem solicitados enquanto o navegador processa itens <head> críticos.

  • Talvez não seja possível introduzir a prioridade de busca como uma prática recomendada no design inicial. Mais adiante no ciclo de desenvolvimento, será possível atribuir as prioridades a diferentes recursos na página e, se elas não corresponderem às suas expectativas, você poderá introduzir a prioridade de busca para otimização adicional.

Dicas para usar pré-carregamentos

Lembre-se do seguinte ao usar pré-carregamentos:

  • A inclusão de um pré-carregamento em cabeçalhos HTTP o coloca antes de todo o restante na ordem de carregamento.
  • Geralmente, os pré-carregamentos são carregados na ordem em que o analisador os chega para qualquer item acima da prioridade "Média". Tenha cuidado ao incluir pré-carregamentos no início do seu HTML.
  • Os pré-carregamentos de fontes provavelmente funcionam melhor no final da cabeça ou no início do corpo.
  • Os pré-carregamentos de importação (dinâmico import() ou modulepreload) precisam ser executados depois da tag de script que precisa da importação. Portanto, verifique se o script é carregado ou analisado primeiro para que ele possa ser avaliado durante o carregamento das dependências.
  • Os pré-carregamentos de imagens têm prioridade "Baixa" ou "Média" por padrão. Ordene-as em relação a scripts assíncronos e outras tags de prioridade baixa ou mais baixa.

Histórico

A busca de prioridade foi testada pela primeira vez no Chrome como um teste de origem em 2018 e novamente em 2021 com o atributo importance. Na época, ele era chamado de Dicas de prioridade. Desde então, a interface mudou para fetchpriority no HTML e priority na API Fetch do JavaScript como parte do processo de padrões da Web. Para reduzir a confusão, agora chamamos essa prioridade de busca da API.