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

Demián Renzulli
Demián Renzulli

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

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

Avaliar o desempenho

Primeiro, defina o desempenho de referência:

  1. Clique em Remixar para editar para tornar o projeto editável.
  2. Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia modo tela cheia.
  3. Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.
  4. Clique na guia Rede.

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

  6. 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 Network mostrando os tempos de carregamento de product-details.html

Para melhorar a navegação, insira uma tag prefetch na página de destino para fazer a pré-busca da 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 corretos e a determinar se o recurso já está no cache. Exemplos de valores para esse atributo: document, script, style, font, image e outros.

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

  1. Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia modo tela cheia.
  2. Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.
  3. Clique na guia Rede.

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

  5. Desmarque a caixa de seleção Desativar cache.

  6. Atualize o app.

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

Painel Network mostrando o product-details.html pré-buscado.

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

Reavalie a performance

  1. Atualize 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 Time mostra que o tempo necessário para o documento carregar agora é de cerca de 10 ms.

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

Painel Network mostrando product-details.html recuperado do cache de pré-busca.

Crédito extra: use prefetch como um aprimoramento progressivo

A pré-busca é mais bem implementada como uma melhoria progressiva para usuários que estão navegando em conexões rápidas. Você pode usar a API Network Information para verificar as condições de rede e, com base nelas, injetar dinamicamente tags de pré-busca. Dessa forma, você pode minimizar o consumo de dados e economizar custos para os usuários com planos de dados lentos ou caros.

Para implementar a pré-busca adaptável, 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 código abaixo ao método public/script.js para declarar uma função que injeta dinamicamente a tag prefetch quando o usuário estiver 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:

  • Ele 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, ela 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 HTML document no atributo as.
  • Por fim, ele injeta o script dinamicamente no head da página.

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

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

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

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

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

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

  1. Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia modo tela cheia.
  2. Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.
  3. Clique na guia Rede.
  4. Na lista suspensa Limitação, selecione On-line.
  5. Atualize o app.

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

Painel Network mostrando o product-details.html pré-buscado.

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

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

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

Painel Network mostrando o product-details.html que não está sendo pré-buscado.

O cabeçalho HTTP Link pode ser usado para fazer a pré-busca do mesmo tipo de recurso que a tag link. A decisão sobre quando usar um ou outro depende principalmente da sua preferência, já que a diferença de desempenho é insignificante. Nesse caso, ela é usada para fazer a pré-busca do 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 para a página de destino:

  1. Abra o arquivo server.js e procure o gerenciador get() para o URL raiz: /.
  2. Adicione a seguinte linha ao início do gerenciador:
app.get('/', function(request, response) {
    response.set('Link', '</style-product.css>; rel=prefetch');
    response.sendFile(__dirname + '/views/index.html');
});
  1. Para visualizar o site, pressione Ver app. Em seguida, pressione Tela cheia modo tela cheia.
  2. Pressione "Control + Shift + J" (ou "Command + Option + J" no Mac) para abrir o DevTools.
  3. Clique na guia Rede.
  4. Atualize 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 a pré-busca de style-product.css.

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

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

O arquivo style-product.css é recuperado do "cache de pré-busca" e o carregamento levou apenas 12 ms.