Duas formas de pré-busca: tags <link> e cabeçalhos HTTP

Demián Renzulli
Demián Renzulli

Neste codelab, você vai implementar a pré-busca de duas maneiras: com <link rel="prefetch"> e com o cabeçalho HTTP Link.

O app de exemplo é um site com uma página de destino promocional que oferece um desconto especial na camiseta mais vendida da loja. Como a página de destino tem um link para um único produto, é seguro presumir que uma alta porcentagem de usuários vai navegar até a página de detalhes do produto. Isso faz com que a página do produto seja um ótimo candidato para pré-busca na página de destino.

Avaliar o desempenho

Primeiro, estabeleça o desempenho de referência:

  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
  2. Clique na guia Rede.

  3. Na lista suspensa Limitação, selecione 3G rápido para simular um tipo de conexão lenta.

  4. Para carregar a página do produto, clique em Comprar agora no app de exemplo.

A página product-details.html leva cerca de 600 ms para carregar:

Painel de rede mostrando os tempos de carregamento de &quot;product-details.html&quot;

Para melhorar a navegação, insira uma tag prefetch na página de destino para pré-buscar a página product-details.html:

  • Adicione o seguinte elemento <link> ao cabeçalho do arquivo views/index.html:
<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">

      <link rel="prefetch" href="/product-details.html" as="document">
      ...
</head>

O atributo as é opcional, mas recomendado. Ele ajuda o navegador a definir os cabeçalhos certos e determinar se o recurso já está no cache. Exemplos de valores para esse atributo incluem: document, script, style, font, image e outros.

Para verificar se a pré-busca está funcionando:

  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
  2. Clique na guia Rede.

  3. Na lista suspensa Limitação, selecione 3G rápido para simular um tipo de conexão lenta.

  4. Desmarque a caixa de seleção "Desativar cache".

  5. Recarregue o app.

Agora, quando a página de destino é carregada, a página product-details.html também é carregada, mas com a prioridade mais baixa:

Painel de rede mostrando o pré-busca de &quot;product-details.html&quot;.

A página é mantida no cache HTTP por cinco minutos. Depois disso, as regras normais de Cache-Control para o documento são aplicadas. Nesse caso, product-details.html tem um cabeçalho cache-control com um valor de public, max-age=0, o que significa que a página é mantida por um total de cinco minutos.

Reavaliar a performance

  1. Recarregue o app.
  2. Para carregar a página do produto, clique em Comprar agora no app de exemplo.

Confira o painel Rede. Há duas diferenças em comparação com o rastreamento de rede inicial:

  • A coluna Tamanho mostra "cache de pré-busca", o que significa que esse recurso foi recuperado do cache do navegador, e não da rede.
  • A coluna Tempo mostra que o tempo necessário para carregar o documento agora é de cerca de 10 ms.

Isso representa uma redução de aproximadamente 98% em comparação com a versão anterior, que levava cerca de 600 ms.

Painel de rede mostrando &quot;product-details.html&quot; recuperado do cache de pré-busca.

Crédito extra: use prefetch como um aprimoramento progressivo

A pré-busca é melhor implementada como uma melhoria progressiva para usuários que navegam em conexões rápidas. Você pode usar a API Network Information para verificar as condições da rede e, com base nisso, injetar dinamicamente tags de pré-busca. Assim, você pode minimizar o consumo de dados e economizar custos para usuários com planos de dados lentos ou caros.

Para implementar a pré-busca adaptativa, primeiro remova a tag <link rel="prefetch"> de views/index.html:

<!doctype html>
  <html>
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
       <link rel="prefetch" href="/product-details.html" as="document">
       ...
    </head>

Em seguida, adicione o seguinte código a public/script.js para declarar uma função que injeta dinamicamente a tag prefetch quando o usuário está em uma conexão rápida:

function injectLinkPrefetchIn4g(url) {
    if (window.navigator.connection.effectiveType === '4g') {
        //generate link prefetch tag
        const linkTag = document.createElement('link');
        linkTag.rel = 'prefetch';
        linkTag.href = url;
        linkTag.as = 'document';

        //inject tag in the head of the document
        document.head.appendChild(linkTag);
    }
}

A função funciona da seguinte maneira:

  • Ela verifica a propriedade effectiveType da API Network Information para determinar se o usuário está em uma conexão 4G (ou mais rápida).
  • Se essa condição for atendida, ele vai gerar uma tag <link> com prefetch como o tipo de dica, transmitir o URL que será pré-buscado no atributo href e indicar que o recurso é um document HTML no atributo as.
  • Por fim, ele injeta o script de forma dinâmica no head da página.

Em seguida, adicione script.js a views/index.html, antes da tag de fechamento </body>:

<body>
      ...
      <script src="/script.js"></script>
</body>

Solicitar script.js no final da página garante que ele seja carregado e executado depois que a página for analisada e carregada.

Para garantir que a pré-busca não interfira nos recursos críticos da página atual, adicione o snippet de código a seguir para chamar injectLinkPrefetchIn4g() no evento window.load:

<body>
      ...
      <script src="/script.js"></script>
      <script>
           window.addEventListener('load', () => {
                injectLinkPrefetchIn4g('/product-details.html');
           });
      </script>
</body>

Agora, a página de destino faz pré-busca de product-details.html apenas em conexões rápidas. Para verificar isso:

  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
  2. Clique na guia Rede.
  3. Na lista suspensa Limitação, selecione On-line.
  4. Recarregue o app.

Você vai ver product-details.html no painel "Rede":

Painel de rede mostrando o pré-busca de &quot;product-details.html&quot;.

Para verificar se a página do produto não é pré-buscada em conexões lentas:

  1. Na lista suspensa "Restrição", selecione 3G lento.
  2. Recarregue o app.

O painel Rede deve incluir apenas os recursos da página de destino sem product-details.html:

Painel de rede mostrando que &quot;product-details.html&quot; não está sendo pré-buscado.

O cabeçalho HTTP Link pode ser usado para pré-buscar o mesmo tipo de recursos que a tag link. A decisão de usar um ou outro depende principalmente da sua preferência, já que a diferença de desempenho é insignificante. Nesse caso, você vai usar o recurso para pré-buscar o CSS principal da página do produto e melhorar ainda mais a renderização.

Adicione um cabeçalho HTTP Link para style-product.css na resposta do servidor da página de destino:

  1. Abra o arquivo server.js e procure o manipulador get() para o URL raiz: /.
  2. Adicione a seguinte linha no início do manipulador:
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. Pressione "Control+Shift+J" (ou "Command+Option+J" no Mac) para abrir o DevTools.
  2. Clique na guia Rede.
  3. Recarregue o app.

O style-product.css agora é pré-buscado com a prioridade mais baixa depois que a página de destino é carregada:

Painel de rede mostrando o pré-busca de style-product.css.

Para acessar a página do produto, clique em Comprar agora. Confira o painel Rede:

Painel de rede mostrando style-product.css recuperado do cache de pré-busca.

O arquivo style-product.css foi recuperado do "cache de pré-busca" e levou apenas 12 ms para ser carregado.