Pré-carregue recursos essenciais para melhorar a velocidade de carregamento

Quando você abre uma página da Web, o navegador solicita o documento HTML de um servidor, analisa seu conteúdo e envia solicitações separadas para qualquer recurso referenciado. Como desenvolvedor, você já conhece todos os recursos de que sua página precisa e quais deles são os mais importantes. Você pode usar esse conhecimento para solicitar os recursos críticos com antecedência e acelerar o processo de carregamento. Esta postagem explica como fazer isso com o <link rel="preload">.

Como o pré-carregamento funciona

O pré-carregamento é mais adequado para recursos normalmente descobertos com atraso pelo navegador.

Captura de tela do painel Network do Chrome DevTools.
Neste exemplo, a fonte Pacifico é definida na folha de estilo com uma regra @font-face. O navegador carrega o arquivo de fonte somente depois de concluir o download e a análise da folha de estilo.

Ao pré-carregar determinado recurso, você está informando ao navegador que gostaria de buscá-lo antes do que o navegador o descobriria, porque você tem certeza de que ele é importante para a página atual.

Captura de tela do painel Network do Chrome DevTools após aplicar o pré-carregamento.
Neste exemplo, a fonte Pacifico é pré-carregada, então o download acontece em paralelo com a folha de estilo.

A cadeia de solicitação crítica representa a ordem dos recursos que são priorizados e buscados pelo navegador. O Lighthouse identifica os recursos que estão no terceiro nível dessa rede como descobertos tardiamente. É possível usar a auditoria Pré-carregar solicitações de chave para identificar quais recursos devem ser pré-carregados.

Auditoria de solicitações principais de pré-carregamento do Lighthouse.

É possível pré-carregar recursos adicionando uma tag <link> com rel="preload" ao cabeçalho do documento HTML:

<link rel="preload" as="script" href="critical.js">

O navegador armazena em cache os recursos pré-carregados para que estejam disponíveis imediatamente, quando necessário. Ele não executa os scripts nem aplica as folhas de estilo.

As dicas de recursos, como preconnect e prefetch, são executadas de acordo com as necessidades do navegador. O preload, por outro lado, é obrigatório para o navegador. Os navegadores modernos já são muito bons em priorizar recursos. Por isso, é importante usar o preload com moderação e pré-carregar apenas os recursos mais críticos.

Os pré-carregamentos não usados acionam um aviso do console no Chrome, aproximadamente três segundos após o evento load.

Aviso do Console do Chrome DevTools sobre recursos pré-carregados não utilizados.

Casos de uso

Pré-carregamento de recursos definidos no CSS

Fontes definidas com regras @font-face ou imagens de plano de fundo definidas em arquivos CSS não são descobertas até que o navegador faça o download e analise esses arquivos CSS. O pré-carregamento desses recursos garante que eles sejam buscados antes do download dos arquivos CSS.

Pré-carregamento de arquivos CSS

Caso esteja usando a abordagem CSS crítica, você divide o CSS em duas partes. O CSS essencial necessário para renderizar o conteúdo acima da dobra é inline no <head> do documento, e o CSS não essencial geralmente é carregado lentamente com JavaScript. Aguardar a execução do JavaScript antes de carregar um CSS não essencial pode causar atrasos na renderização quando os usuários rolam a tela. Por isso, é recomendável usar <link rel="preload"> para iniciar o download mais cedo.

Pré-carregamento de arquivos JavaScript

Como os navegadores não executam arquivos pré-carregados, o pré-carregamento é útil para separar a busca da execução, o que pode melhorar métricas como o tempo para interação da página. O pré-carregamento funciona melhor se você dividir os pacotes JavaScript e pré-carregar apenas blocos críticos.

Como implementar rel=preload

A maneira mais simples de implementar o preload é adicionar uma tag <link> ao <head> do documento:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

Fornecer o atributo as ajuda o navegador a definir a prioridade do recurso pré-buscado de acordo com o tipo, definir os cabeçalhos certos e determinar se o recurso já existe no cache. Os valores aceitos para esse atributo incluem: script, style, font, image e outros.

Alguns tipos de recursos, como fontes, são carregados no modo anônimo. Para aqueles que você precisa definir o atributo crossorigin com preload:

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

Os elementos <link> também aceitam um atributo type, que contém o tipo MIME do recurso vinculado. Os navegadores usam o valor do atributo type para garantir que os recursos sejam pré-carregados somente se o tipo de arquivo for compatível. Se um navegador não oferecer suporte ao tipo de recurso especificado, ele vai ignorar o <link rel="preload">.

Também é possível pré-carregar qualquer tipo de recurso com o cabeçalho HTTP Link:

Link: </css/style.css>; rel="preload"; as="style"

Uma vantagem de especificar preload no cabeçalho HTTP é que o navegador não precisa analisar o documento para descobri-lo, o que pode oferecer pequenas melhorias em alguns casos.

Pré-carregar módulos JavaScript com webpack

Se você estiver usando um bundler de módulo que cria arquivos de build do seu aplicativo, será necessário verificar se ele oferece suporte à injeção de tags de pré-carregamento. Com o webpack versão 4.6.0 ou mais recente, o pré-carregamento é compatível com o uso de comentários mágicos em import():

import(_/* webpackPreload: true */_ "CriticalChunk")

Se você estiver usando uma versão mais antiga do webpack, use um plug-in de terceiros, como o preload-webpack-plugin.

Efeitos do pré-carregamento nas Core Web Vitals

O pré-carregamento é uma poderosa otimização de desempenho que afeta a velocidade de carregamento. Essas otimizações podem levar a alterações nas Core Web Vitals do seu site, e é importante conhecê-las.

Maior exibição de conteúdo (LCP)

O pré-carregamento tem um efeito poderoso na Largest Contentful Paint (LCP) quando se trata de fontes e imagens, já que tanto os nós de imagem quanto os de texto podem ser candidatos à LCP. Imagens principais e grandes execuções de texto renderizadas com fontes da Web podem se beneficiar significativamente de uma dica de pré-carregamento bem posicionada. Além disso, elas devem ser usadas quando houver oportunidades de exibir esses trechos importantes do conteúdo ao usuário com mais rapidez.

No entanto, é preciso ter cuidado com o pré-carregamento e outras otimizações. Em especial, evite pré-carregar recursos demais. Se muitos recursos forem priorizados, efetivamente nenhum deles será. Os efeitos de dicas de pré-carregamento excessivos serão especialmente prejudiciais para aquelas em redes mais lentas, em que a contenção de largura de banda será mais evidente.

Em vez disso, concentre-se em alguns recursos de alto valor que você sabe que se beneficiarão de um pré-carregamento bem posicionado. Ao pré-carregar fontes, verifique se as fontes estão no formato WOFF 2.0 para reduzir ao máximo o tempo de carregamento de recursos. Como o WOFF 2.0 tem um excelente suporte a navegadores, o uso de formatos mais antigos, como WOFF 1.0 ou TrueType (TTF), vai atrasar sua LCP se o candidato à LCP for um nó de texto.

Quando se trata de LCP e JavaScript, é bom garantir que você esteja enviando a marcação completa do servidor para que o scanner de pré-carregamento do navegador funcione corretamente. Se você estiver oferecendo uma experiência que depende totalmente de JavaScript para renderizar marcação e não puder enviar HTML renderizado pelo servidor, seria vantajoso impedi-la de verificar o pré-carregamento do navegador e pré-carregar recursos que, de outra forma, só seriam detectáveis quando o JavaScript termina de carregar e executar.

Cumulative Layout Shift (CLS)

A Cumulative Layout Shift (CLS, na sigla em inglês) é uma métrica especialmente importante no que diz respeito a fontes da Web, e a CLS tem interação significativa com fontes da Web que usam a propriedade CSS font-display para gerenciar a forma como as fontes são carregadas. Para minimizar as mudanças de layout relacionadas a fontes na Web, considere as seguintes estratégias:

  1. Pré-carregue fontes usando o valor padrão block para font-display. Esse é um equilíbrio delicado. Bloquear a exibição de fontes sem um substituto pode ser considerado um problema de experiência do usuário. Por um lado, carregar fontes com font-display: block; elimina as mudanças de layout relacionadas a fontes na Web. Por outro lado, ainda convém ter essas fontes da Web carregadas o mais rápido possível se elas forem cruciais para a experiência do usuário. Combinar um pré-carregamento com font-display: block; pode ser um comprometimento aceitável.
  2. Pré-carregue fontes usando o valor fallback para font-display. fallback é um meio-termo entre swap e block, porque tem um período de bloqueio extremamente curto.
  3. Use o valor optional para font-display sem um pré-carregamento. Se uma fonte da Web não for essencial para a experiência do usuário, mas ainda for usada para renderizar uma quantidade significativa de texto da página, use o valor optional. Em condições adversas, o optional vai mostrar o texto da página em uma fonte substituta enquanto carrega a fonte em segundo plano para a próxima navegação. Nessas condições, o resultado final é o CLS aprimorado, já que as fontes do sistema serão renderizadas imediatamente, enquanto os carregamentos de página subsequentes vão carregar a fonte imediatamente sem mudanças de layout.

A CLS é uma métrica difícil de otimizar quando se trata de fontes da Web. Como sempre, faça testes no laboratório, mas confie nos dados de campo para determinar se as estratégias de carregamento de fonte estão melhorando ou piorando a CLS.

Interação com a Next Paint (INP)

Interaction to Next Paint é uma métrica que avalia a capacidade de resposta à entrada do usuário. Como a maior parte da interatividade na Web é orientada por JavaScript, o pré-carregamento do JavaScript que alimenta interações importantes pode ajudar a manter o INP da página mais baixo. No entanto, esteja ciente de que pré-carregar muito JavaScript durante a inicialização pode ter consequências negativas indesejadas se muitos recursos estiverem competindo por largura de banda.

Também é bom prestar atenção na divisão de código. A divisão de código é uma excelente otimização para reduzir a quantidade de JavaScript carregada durante a inicialização, mas as interações podem atrasar caso dependam do carregamento do JavaScript no início. Para compensar, será necessário examinar a intenção do usuário e injetar um pré-carregamento para o(s) bloco(s) necessário(s) de JavaScript antes que a interação ocorra. Um exemplo pode ser o pré-carregamento do JavaScript necessário para validar o conteúdo de um formulário quando algum dos campos desse formulário estiver em foco.

Conclusão

Para melhorar a velocidade da página, pré-carregue recursos importantes que são descobertos posteriormente pelo navegador. O pré-carregamento de tudo seria contraprodutivo, portanto, use preload com moderação e avalie o impacto no mundo real.