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 o conteúdo e envia solicitações separadas para todos os recursos referenciados. Como desenvolvedor, você já sabe todos os recursos de que sua página precisa e quais são os mais importantes. Você pode usar esse conhecimento para solicitar os recursos essenciais com antecedência e acelerar o processo de carregamento. Esta postagem explica como fazer isso com <link rel="preload">.

Como funciona o pré-carregamento

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

Captura de tela do painel &quot;Network&quot; do Chrome DevTools.
Neste exemplo, a fonte Pacifico é definida na folha de estilos com uma regra @font-face. O navegador carrega o arquivo de fonte somente depois de terminar de fazer o download e analisar a folha de estilos.

Ao pré-carregar um determinado recurso, você informa ao navegador que gostaria de buscá-lo antes que ele fosse descoberto, porque tem certeza de que ele é importante para a página atual.

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

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

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

Para pré-carregar recursos, adicione 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 eles fiquem disponíveis imediatamente quando necessário. Ele não executa os scripts nem aplica as folhas de estilo.

As dicas de recursos, por exemplo, preconnect e prefetch, são executadas conforme o navegador achar melhor. 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 preload com moderação e carregar apenas os recursos mais importantes.

Os carregamentos prévios não usados acionam um aviso no console do 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é-carregar recursos definidos em CSS

As 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é-carregar arquivos CSS

Se você estiver usando a abordagem de CSS crítico, vai dividir o CSS em duas partes. O CSS crítico necessário para renderizar o conteúdo acima da dobra é inline no <head> do documento, e o CSS não crítico geralmente é carregado de forma lazy com JavaScript. Esperar a execução do JavaScript antes de carregar o CSS não essencial pode causar atrasos na renderização quando os usuários rolam a página. Por isso, é recomendável usar <link rel="preload"> para iniciar o download mais cedo.

Pré-carregar 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 de resposta. O pré-carregamento funciona melhor se você dividir seus pacotes JavaScript e pré-carregar apenas os blocos críticos.

Como implementar rel=preload

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

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

O fornecimento do atributo as ajuda o navegador a definir a prioridade do recurso pré-buscado de acordo com o tipo, definir os cabeçalhos corretos 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 esses casos, defina 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 apenas se o tipo de arquivo tiver suporte. 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 pelo cabeçalho HTTP Link:

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

Um benefício de especificar preload no cabeçalho HTTP é que o navegador não precisa analisar o documento para detectá-lo, o que pode oferecer pequenas melhorias em alguns casos.

Pré-carregar módulos JavaScript com o webpack

Se você estiver usando um bundler de módulos que cria arquivos de build do seu aplicativo, verifique se ele oferece suporte à injeção de tags de pré-carregamento. Com a versão 4.6.0 ou mais recente do webpack, o pré-carregamento é compatível com o uso de comentários mágicos no 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 otimização de desempenho eficiente que afeta a velocidade de carregamento. Essas otimizações podem levar a mudanças nos Core Web Vitals do seu site, e é importante estar ciente delas.

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

O pré-carregamento tem um efeito poderoso na maior exibição de conteúdo (LCP, na sigla em inglês) quando se trata de fontes e imagens, já que imagens e nós de texto podem ser candidatos à LCP. Imagens principais e grandes quantidades de texto renderizadas usando fontes da Web podem se beneficiar significativamente de uma dica de pré-carregamento bem posicionada e devem ser usadas quando houver oportunidades de entregar esses bits importantes de conteúdo ao usuário mais rapidamente.

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

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

No caso do LCP e do JavaScript, é importante enviar uma marcação completa do servidor para que o leitor de pré-carregamento do navegador funcione corretamente. Se você estiver oferecendo uma experiência que depende inteiramente do JavaScript para renderizar a marcação e não puder enviar HTML renderizado pelo servidor, seria vantajoso intervir onde o scanner de pré-carregamento do navegador não pode e pré-carregar recursos que só seriam detectáveis quando o JavaScript terminar de carregar e executar.

Cumulative Layout Shift (CLS)

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

  1. Pré-carregue fontes usando o valor padrão de 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, o carregamento de fontes com font-display: block; elimina as mudanças de layout relacionadas a fontes da Web. Por outro lado, você ainda vai querer carregar essas fontes da Web 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 compromisso aceitável.
  2. Pré-carregue fontes usando o valor fallback para font-display. fallback é um compromisso entre swap e block, porque tem um período de bloqueio extremamente curto.
  3. Use o valor optional para font-display sem pré-carregar. Se uma fonte da Web não for crucial para a experiência do usuário, mas ainda for usada para renderizar uma quantidade significativa de texto na página, use o valor optional. Em condições adversas, 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. O resultado líquido dessas condições é uma melhoria na CLS, já que as fontes do sistema são renderizadas imediatamente, enquanto os carregamentos de página subsequentes carregam a fonte imediatamente sem mudanças de layout.

A CLS é uma métrica difícil de otimizar para 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 fontes estão melhorando ou piorando o CLS.

Interaction to Next Paint (INP)

A métrica "Interaction to Next Paint" mede a capacidade de resposta à entrada do usuário. Como a maior parte da interatividade na Web é impulsionada pelo JavaScript, o pré-carregamento de JavaScript que gera interações importantes pode ajudar a manter o INP de uma página mais baixo. No entanto, o carregamento antecipado de muito JavaScript durante a inicialização pode ter consequências negativas não intencionais se muitos recursos estiverem competindo pela largura de banda.

Também é importante ter cuidado com a divisão de código. A divisão de código é uma ótima otimização para reduzir a quantidade de JavaScript carregada durante a inicialização, mas as interações podem ser atrasadas se dependerem do JavaScript carregado no início da interação. Para compensar isso, você precisa examinar a intenção do usuário e injetar um pré-carregamento para os fragmentos necessários de JavaScript antes que a interação ocorra. Um exemplo seria pré-carregar o JavaScript necessário para validar o conteúdo de um formulário quando qualquer um dos campos do formulário estiver em foco.

Conclusão

Para melhorar a velocidade da página, pré-carregue recursos importantes que são descobertos tarde pelo navegador. Carregar tudo de antemão seria contraproducente. Use preload com moderação e meça o impacto no mundo real.