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 quaisquer recursos referenciados. Como desenvolvedor, você já conhece todos os recursos necessários para sua página e quais deles são os mais importantes. Use esse conhecimento para solicitar os recursos essenciais com antecedência e acelerar o processo de carregamento. Esta postagem explica como fazer isso com o <link rel="preload">.

Como funciona o pré-carregamento

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

Captura de tela do painel &quot;Network&quot; 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 após concluir o download e a análise da folha de estilo.

Ao pré-carregar um determinado recurso, você está informando ao navegador que gostaria de buscá-lo antes do que o navegador o descobriria, porque 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ções 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. Use a auditoria Pré-carregar solicitações principais para identificar quais recursos devem ser pré-carregados.

Auditoria de pré-carregamento de solicitações principais 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 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 quando o navegador entende que é adequado. O preload, por outro lado, é obrigatório para o navegador. Os navegadores modernos já são bons em priorizar recursos, por isso é importante usar preload com moderação e pré-carregar apenas os recursos mais importantes.

Os pré-carregamentos não utilizados 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

Se você estiver usando a abordagem crítica de CSS, divida 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 o JavaScript. A espera da execução do JavaScript antes de carregar 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, é útil separar a busca da execução, o que pode melhorar métricas como o tempo até a 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 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 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 eles, é preciso 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 <link rel="preload">.

Também é possível pré-carregar qualquer tipo de recurso usando 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 detectá-lo, o que pode oferecer pequenas melhorias em alguns casos.

Pré-carregamento de módulos JavaScript com webpack

Caso esteja usando um bundler de módulo que crie arquivos de compilação do aplicativo, verifique se ele oferece suporte à injeção de tags de pré-carregamento. Com o webpack versão 4.6.0 ou posterior, o pré-carregamento é compatível com o uso de comentários mágicos (links em inglês) dentro de import():

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

Se você tiver 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 alterações nas 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) quando se trata de fontes e imagens, já que tanto as imagens quanto os nós de texto podem ser candidatos à LCP. Imagens principais e grandes execuções de texto renderizados usando fontes da Web podem se beneficiar significativamente de uma dica de pré-carregamento bem posicionada e devem ser usadas quando houver oportunidades de fornecer esses trechos importantes de conteúdo ao usuário mais rapidamente.

No entanto, é importante ter cuidado com o pré-carregamento e outras otimizações. Especificamente, evite o pré-carregamento de muitos recursos. Se muitos recursos forem priorizados, nenhum deles será. Os efeitos das dicas de pré-carregamento excessivas serão especialmente prejudiciais para as pessoas em redes mais lentas, onde 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 você está exibindo fontes no formato WOFF 2.0 para reduzir ao máximo o tempo de carregamento dos 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 a LCP for um nó de texto.

Quando se trata de LCP e JavaScript, você precisa garantir que está 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 inteiramente de JavaScript para renderizar a marcação e não pode enviar HTML renderizado pelo servidor, seria vantajoso entrar em que o scanner de pré-carregamento do navegador não consegue e pré-carregar recursos que só seriam descobertos quando o JavaScript terminasse de carregar e executar.

Cumulative Layout Shift (CLS)

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

  1. Pré-carregue fontes ao usar 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, o carregamento de fontes com font-display: block; elimina mudanças de layout relacionadas a fontes da Web. Por outro lado, você ainda quer que essas fontes da Web sejam carregadas o mais rápido possível, caso elas sejam 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 ao usar o valor fallback para font-display. fallback é uma combinação entre swap e block, porque tem um período de bloqueio extremamente curto.
  3. Use o valor optional para font-display sem 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 é a melhoria da CLS, já que as fontes do sistema são renderizadas imediatamente. Os carregamentos de página subsequentes carregam 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 seus dados de campo para determinar se suas estratégias de carregamento de fontes estão melhorando ou melhorando a CLS.

Interação com a próxima exibição (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 é impulsionada pelo JavaScript, o pré-carregamento do JavaScript que impulsiona interações importantes pode ajudar a reduzir o INP de uma página. No entanto, esteja ciente de que o pré-carregamento de JavaScript demais durante a inicialização pode trazer consequências negativas não intencionais se muitos recursos estiverem competindo por largura de banda.

Também convém ter cuidado com a forma como você lida com a divisão de código. A divisão de código é uma excelente otimização para reduzir a quantidade de JavaScript carregado durante a inicialização, mas as interações poderão ser atrasadas se dependerem do JavaScript carregado logo no início da interação. Para compensar isso, 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 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 tardiamente pelo navegador. Pré-carregar tudo seria contraprodutivo. Portanto, use preload com moderação e meça o impacto no mundo real.