Otimizar o carregamento de recursos com a API Fetch Priority

A API Fetch Priority indica a prioridade relativa dos recursos para o navegador. Ela pode permitir o carregamento ideal e melhorar as Core Web Vitals.

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 tentar fazer o download dos recursos em uma ordem ideal. Essas prioridades podem depender do tipo de recurso e da localização dele no documento. Por exemplo, as imagens na janela de visualização podem ter uma prioridade High, enquanto a prioridade para CSS bloqueadores de renderização com carregamento antecipado por <link>s no <head> pode ser Very High. Os navegadores são muito eficientes em atribuir prioridades que funcionam bem, mas que podem não ser ideais em todos os casos.

Neste artigo, vamos falar sobre a API Fetch Preview e o atributo HTML fetchpriority, que permite indicar a prioridade relativa de um recurso (high ou low). A prioridade de busca pode ajudar a otimizar as Core Web Vitals.

Resumo

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

  • Aumente a prioridade da imagem LCP especificando fetchpriority="high" no elemento de imagem, fazendo com que a LCP aconteça mais cedo.
  • Aumente a prioridade dos scripts async usando semântica melhor do que a hack atual usada com frequência (inserindo um <link rel="preload"> para o script async).
  • Reduza a prioridade de scripts de corpo mais recente para permitir um melhor sequenciamento com imagens.
Uma visualização em tira de filme comparando dois testes da página inicial do Google Voos. Na parte inferior, a prioridade de busca é usada para aumentar a prioridade da imagem principal, resultando em uma redução de 0,7 segundo na LCP.
Melhoria da prioridade de busca melhorando 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 alguma influência, mas limitada, sobre a prioridade de recursos usando pré-carregamento e pré-conexão. A prioridade de busca complementa estas Dicas de recursos, mas é essencial entender onde todas elas se encaixam. O pré-carregamento permite que você informe ao navegador sobre os recursos críticos que deseja carregar antes que sejam descobertos naturalmente. Isso é especialmente útil para recursos que não são facilmente descobertos, 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 as conexões com servidores de origem cruzada e pode ajudar a melhorar métricas como o Time-to-first-byte. Ela é útil quando você conhece uma origem, mas não necessariamente o URL exato de um recurso que será necessário.

A prioridade de busca é um indicador baseado em marcação (disponível no atributo fetchpriority) que os desenvolvedores podem usar para indicar a prioridade relativa de um recurso específico. Também é possível usar essas dicas com 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. Usar 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 pode ajudar a agilizar o carregamento da imagem.

A prioridade de busca está disponível no Chrome 101 ou mais recente.

Prioridade do recurso

A sequência de download de recursos depende da prioridade atribuída do navegador para cada recurso na página. Diferentes fatores podem afetar a lógica do cálculo de prioridade. Por exemplo:

  • CSS, fontes, scripts, imagens e recursos de terceiros têm prioridades diferentes.
  • O local ou a ordem em que você faz referência aos recursos no documento também afeta a prioridade deles.
  • A dica de recurso preload ajuda o navegador a descobrir um recurso mais rapidamente e, assim, carregá-lo antes que o documento o carregue e afete a prioridade.
  • Mudanças no cálculo de prioridade para scripts async ou defer.

A tabela a seguir considera esses fatores para mostrar como a maioria dos recursos está priorizada e sequenciada no Chrome.

  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. Você pode verificar a prioridade atribuída a diferentes recursos ao carregar uma página na guia Rede das Ferramentas do Chrome Dev. (Lembre-se de incluir a coluna de prioridade clicando com o botão direito nos títulos 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 do 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 do tipo de recurso = "script" na página de detalhes das notícias da BBC

Quando as prioridades mudam, é possível usar a configuração Linhas de solicitação grande para ver a prioridade inicial e a final. Isso também aparece em uma dica, independentemente da configuração de Linhas de solicitação grande.

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.
Como verificar a prioridade inicial e final no DevTools

Quando você precisa da prioridade de busca?

O conhecimento da lógica de priorização do navegador permite que você tenha alguns botões para ajustar a ordem dos downloads. Você pode

  1. Coloque as tags de recurso, como <script> e <link>, dependendo da ordem em que você quer fazer o download delas. Recursos com a mesma prioridade geralmente são carregados na ordem em que são descobertos.
  2. Use a dica de recurso preload para fazer o download dos recursos necessários com antecedência, principalmente os que não são descobertos facilmente pelo navegador.
  3. Use async ou defer para fazer o download de scripts sem bloquear outros recursos.
  4. 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.

Essas técnicas ajudam a controlar o cálculo prioritário do navegador, melhorando o desempenho e as Core Web Vitals. Por exemplo, quando uma imagem de plano de fundo crítica é pré-carregada, ela pode ser descoberta bem antes, melhorando a Maior exibição de conteúdo (LCP).

Às vezes, esses identificadores podem não ser suficientes para priorizar os recursos da maneira ideal para seu aplicativo. Veja alguns cenários em que a prioridade de busca pode ser útil:

  1. Você tem várias imagens acima da dobra, mas todas não precisam ter a mesma prioridade. Por exemplo, em um carrossel de imagens, apenas a primeira imagem visível precisa de uma prioridade maior em comparação com as outras.
  2. As imagens principais dentro da janela de visualização normalmente começam com uma prioridade "Baixa". Uma mudança no Chrome 117 define as cinco primeiras imagens grandes como "Média", mas isso pode ou não incluir a imagem de fundo. 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 da imagem. Fornecer a prioridade de busca na marcação permite que a imagem comece com uma prioridade "Alta" e comece a carregar muito mais cedo.

    O pré-carregamento ainda é necessário para a descoberta antecipada de imagens LCP incluídas como planos de fundo do CSS e pode ser combinado com a prioridade de busca incluindo o fetchpriority='high' no pré-carregamento. Caso contrário, ela ainda vai começar com uma prioridade "Baixa" ou "Média" para imagens.
  3. Declarar scripts como async ou defer instrui o navegador a carregá-los de forma assíncrona. No entanto, como visto na tabela anterior, esses scripts também recebem uma prioridade "Baixa". Você pode aumentar a prioridade e garantir o download assíncrono, principalmente para scripts essenciais para a experiência do usuário.
  4. É possível usar a API JavaScript fetch() para buscar recursos ou dados de maneira assíncrona. A busca recebe uma prioridade "Alta" do navegador. Pode haver situações em que você não quer que todas as suas buscas sejam executadas com prioridade "Alta" e prefira usar uma prioridade de busca diferente. Isso pode ser útil ao executar chamadas de API em segundo plano e misturá-las com as chamadas de API que respondem à entrada do usuário, como acontece com o preenchimento automático. As chamadas de API em segundo plano podem ser marcadas com prioridade "Baixa", e as chamadas de API interativas podem ser marcadas como prioridade "Alta".
  5. O navegador atribui uma prioridade "Alta" a CSS e fontes, mas todos esses recursos podem não ser igualmente importantes ou necessários para a LCP. Use a opção "Buscar prioridade" para diminuir a prioridade de alguns desses recursos.

O atributo fetchpriority

Você pode fornecer uma prioridade de busca usando o atributo HTML fetchpriority. Você pode usar o atributo com as tags link, img e script. O atributo permite especificar a prioridade de tipos de recursos, como CSS, fontes, scripts e imagens quando são baixados usando as tags suportadas. O atributo fetchpriority aceita um destes três valores:

  • high: você considera o recurso de alta prioridade e quer que o navegador o priorize, desde que a heurística dele não impeça que isso aconteça.
  • low: você considera o recurso de baixa prioridade e quer que o navegador diminua a prioridade dele se a heurística permitir.
  • auto: é o valor padrão quando você não tem preferência e permite que o navegador decida a prioridade adequada.

Confira alguns exemplos de como usar o atributo fetchpriority na marcação e 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>

Prioridade do navegador e fetchpriority

É possível aplicar o atributo fetchpriority a diferentes recursos, conforme mostrado na figura a seguir, para aumentar ou reduzir a prioridade calculada. O caractere fetchpriority="auto" (◉) em cada linha indica a prioridade padrão para esse tipo de recurso (também disponível como um documento Google).

  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/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

Observe que fetchpriority define a prioridade relativa, ou seja, aumenta ou diminui a prioridade padrão por um valor adequado, em vez de definir explicitamente a prioridade como "Alta" ou "Baixa", e o navegador decide a prioridade relativa. Muitas vezes, esse valor é "Alto" ou "Baixo", mas nem sempre. Por exemplo, CSS crítico com fetchpriority="high" ainda manterá a prioridade "MuitoAlta"/"Mais alta". O uso de fetchpriority="low" nesses itens manterá a prioridade "Alta". Em nenhum dos casos, a prioridade será definida explicitamente como "Alta" ou "Baixa".

Casos de uso

Você pode usar o atributo fetchpriority para lidar com cenários em que pode dar ao navegador uma dica extra sobre com qual prioridade buscar um recurso.

Aumente a prioridade da imagem LCP

Você pode 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,6 s para 1,9 s.

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

Diminuir a prioridade de imagens acima da dobra

É possível usar fetchpriority="low" para diminuir a prioridade de imagens acima da dobra que podem não ser inicialmente importantes, por exemplo, em um carrossel de imagens.

<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, usamos esse recurso para diminuir a prioridade das imagens que não aparecem no carregamento. Isso ajudou a reduzir o tempo de carregamento 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.

Diminuir a prioridade de recursos pré-carregados

Para impedir que recursos pré-carregados concorram com outros recursos críticos, você pode dar uma dica para reduzir a prioridade deles. Você pode usar 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 necessários para tornar algumas partes da página interativas são essenciais, mas não devem bloquear outros recursos. Você pode marcá-los como assíncronos com alta prioridade.

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

Os scripts não podem ser marcados como assíncronos se dependerem de estados específicos do DOM. No entanto, se eles estiverem mais abaixo na página, será possível fazer o download deles com uma prioridade mais baixa, conforme mostrado.

<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ê tem várias buscas que podem ser disparadas simultaneamente, é possível usar a prioridade padrão alta para as buscas de dados mais críticas e reduzi-la para 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

A prioridade de busca pode melhorar o desempenho em casos de uso específicos, conforme discutido acima. Há algumas coisas que você precisa saber:

  • O atributo fetchpriority é uma dica, e não uma diretiva. O navegador tentará respeitar a preferência do desenvolvedor. Também é possível que o navegador aplique suas preferências de prioridade de recursos conforme necessário em caso de conflitos.
  • A prioridade de busca não deve ser confundida com um pré-carregamento. Ambos são diferentes porque:

    • O pré-carregamento é uma busca obrigatória, e não uma dica.
    • O pré-carregamento permite que o navegador descubra o recurso com antecedência, mas ainda o busca com a prioridade padrão. Por outro lado, 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.

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

  • Os ganhos perceptíveis devido à priorização serão mais relevantes em ambientes onde mais recursos competem pela largura de banda da rede disponível. Isso é comum em conexões HTTP/1.x em que não é possível fazer downloads paralelos ou em conexões HTTP/2 com baixa largura de banda. A priorização pode resolver gargalos nessas condições.

  • As CDNs não implementam de maneira uniforme a priorização HTTP/2. Mesmo que o navegador comunique a prioridade sugerida usando a prioridade de busca, a CDN não pode atribuir novamente a prioridade dos recursos na ordem necessária. Isso dificulta o teste de prioridade de busca. As prioridades são aplicadas internamente no navegador e com protocolos que oferecem suporte à priorização (HTTP/2 e HTTP/3). Ainda vale a pena usar mesmo para a priorização interna do navegador, independente do suporte de CDN ou origem, porque isso geralmente muda quando os recursos são solicitados pelo navegador. Por exemplo, recursos de baixa prioridade, como imagens, geralmente são impedidos de serem solicitados enquanto o navegador processa os itens <head> críticos.

  • Talvez não seja possível introduzir a prioridade de busca como uma prática recomendada no design inicial. É uma otimização que pode ser aplicada posteriormente no ciclo de desenvolvimento. É possível verificar as prioridades atribuídas a diferentes recursos na página e, se elas não corresponderem às suas expectativas, introduzir prioridade de busca para otimização adicional.

Como usar o pré-carregamento após o Chrome 95

O recurso "Buscar prioridade" estava disponível para teste no Chrome 73 ao 76, mas não foi lançado devido a problemas de priorização com pré-carregamentos corrigidos no Chrome 95. Antes do Chrome 95, as solicitações emitidas pelo <link rel=preload> sempre iniciavam antes de outras solicitações vistas pelo scanner de pré-carregamento, mesmo que as outras solicitações tenham prioridade mais alta.

Com a correção no Chrome 95 e o aprimoramento da prioridade de busca, esperamos que os desenvolvedores comecem a usar o pré-carregamento para o objetivo pretendido: pré-carregar recursos não detectados pelo analisador (fontes, importações, imagens LCP em segundo plano). O posicionamento da dica preload vai ser afetado quando o recurso for pré-carregado. Alguns pontos importantes sobre o uso do pré-carregamento são:

  • Incluir o pré-carregamento em cabeçalhos HTTP fará com que ele pule à frente de todo o restante.
  • Geralmente, os pré-carregamentos são carregados na ordem em que o analisador os chega para qualquer prioridade acima de "Média". Portanto, tenha cuidado ao incluir pré-carregamentos no início do HTML.
  • O pré-carregamento de fontes provavelmente funcionará 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 feitos após a tag do script que precisa da importação (para que o script real seja carregado/analisado primeiro). Basicamente, se a tag de script carregar um script que acionará o carregamento das dependências, verifique se o <link rel=preload> delas está depois da tag do script pai. Caso contrário, as dependências podem acabar sendo carregadas antes do script principal. Na ordem correta, o script principal pode ser analisado/avaliado enquanto as dependências são carregadas.
  • Os pré-carregamentos de imagens têm uma prioridade "Baixa" ou "Média" (sem prioridade de busca) e precisam ser ordenados em relação a scripts assíncronos e outras tags de prioridade baixa ou mais baixa.

Histórico

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

Conclusão

Os desenvolvedores podem estar interessados na prioridade de busca com as correções no comportamento de pré-carregamento e o foco recente nas Core Web Vitals e na LCP. Agora, eles têm outros botões disponíveis para atingir a sequência de carregamento desejada.