Link prefetching
Autor: Rubens Takiguti Ribeiro | Publicado: 2014-12-08T21:22:00-02:00



Introdução

Link prefetching (ou pré-carregamento de links) é um recurso oferecido por navegadores para que sites possam especificar arquivos que devem ser pré-carregados, de forma que estejam prontamente disponíveis quando solicitados, melhorando a performance e consequentemente a usabilidade do site.
Até o momento, apenas os navegadores baseados na engine Gecko (como é o caso do Firefox) implementam o link prefetching, embora a especificação está sendo proposta como recomendação da W3C.
Neste artigo, veremos como o recurso funciona e como tirar proveito para otimização de sites.





Como funciona?
O funcionamento do link prefetching é muito simples. Basta criar links no cabeçalho do documento HTML com o atributo rel com valor "prefetch", como no exemplo abaixo:

&lt;html&gt;
    &lt;head&gt;
        &lt;link rel="prefetch" href="http://www.exemplo.com/pagina.html" /&gt;
        &lt;link rel="prefetch" href="http://www.exemplo.com/imagem.jpg" /&gt;
        &lt;link rel="prefetch" href="http://www.exemplo.com/estilo.css" /&gt;
        ...
    &lt;/head&gt;
    ...

Note que pode ser especificado qualquer tipo de arquivo (html, imagens, css, js, etc).

Esta lista de links são dicas para o navegador. Basicamente o navegador vai carregar estes arquivos quando estiver ocioso. Portanto, é possível especificar alguns arquivos que serão provavelmente acessados futuramente. Não se preocupe: os links marcados como prefetching só serão carregados após todos os arquivos necessários para página corrente estiverem carregados, ou seja, tem baixa prioridade.

A tag link também pode ter o atributo rel com valor "next", indicando a próxima página de uma lista de páginas em sequência. Neste caso, o navegador também faz uso do prefetching e já deixa a próxima página pré-carregada para uso. Porém, para o valor "prev" (página anterior), este comportamento não se aplica, a não ser que o link possua o valor "prev" juntamente com o valor "prefetch", separados por espaço.

Também é possível especificar a lista de links no cabeçalho HTTP do documento enviado. Desta forma, podemos utilizar este recurso em documentos que não são necessariamente HTML. Por exemplo, quando acessar uma imagem, deixar a dica para o navegador pré-carregar um outro arquivo. Para especificar o link no cabeçalho HTTP via PHP, faça assim:

&lt;?php
header('Link: ; rel=prefetch');
header('Link: ; rel=prefetch');
header('Link: ; rel=prefetch');
...




Onde utilizar?
O ideal é utilizar este recurso em pontos do site em que exista grande possibilidade do usuário acessar determinados arquivos no futuro. Por exemplo, supondo um site que requer autenticação, parece-me conveniente indicar como pré-carregamento o link da página de login nas páginas públicas (como a página home do site), caso o usuário não esteja autenticado. Afinal, se alguém acessa uma página pública e não está logado ainda, então tem grande chance de acessar a página de login em breve.

É importante destacar que o link prefetching só carrega o arquivo especificado e não os arquivos dependentes. Ou seja, se você especifica um documento HTML para ser pré-carregado, apenas o HTML será pré-carregado (as imagens, estilos e scripts presentes no HTML não serão).

Atenção: Embora este recurso seja útil em determinadas situações, também é preciso se atentar a um detalhe: quando o navegador carrega um arquivo marcado como prefetching, ele está acessando o servidor, logo, está consumindo recursos. Se o usuário tinha grande chances de acessar o arquivo no futuro, então apenas antecipamos algo que provavelmente irá acontecer. Porém, se você colocar dezenas de arquivos para serem pré-carregados e eles não forem acessados pelo usuário, então significa que você desperdiçou processamento do servidor pra nada. Além disso, é preciso cuidados adicionais para páginas que registram a quantidade de acessos, já que o pré-carregamento de uma página não significa que o usuário realmente acessou a página.



Observações
1 - Como o servidor fica sabendo que a requisição é de prefetching?
Quando o Firefox realiza uma requisição ao servidor para carregar um arquivo sinalizado como prefetching, ele manda um cabeçalho HTTP reservado chamado X-moz com valor "prefetch". No PHP, podemos determinar se a requisição é de prefetching checando a variável $_SERVER conforme o exemplo:

if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch') {
    // É uma requisição prefetch
}

2 - Existe outra forma de pré-carregar arquivos?
Sim, existe. Isso pode ser feito com requisições via JavaScript, por exemplo. A vantagem do link prefetching nativo do navegador é que o usuário tem a liberdade para utilizar ou não o pré-carregamento. No caso do Firefox, é possível desabilitá-lo através da diretiva network.prefetch-next com valor false nas configurações avançadas (acessando about:config na barra de endereço). Assim, usuários que possuem limitação quanto à quantidade de bytes que podem ser baixados pode desabilitar este recurso e só baixar os arquivos que realmente acessar.

3 - O Google Chrome possui algo similar?
Sim, o Google Chrome possui um recurso parecido chamado link prerendering. A diferença é que o prefetching só carrega o arquivo solicitado, enquanto o prerendering carrega o arquivo solicitado e todos os arquivos dependentes (por exemplo, se for solicitado um HTML, serão carregadas as imagens, estilos e scripts associados). Portanto, o prerendering deve ser usado com ainda mais cautela, já que requisita ainda mais arquivos para o servidor e que, talvez, nem sejam usados pelo usuário.

4 - Prefetching de DNS
A resolução de nomes de servidores também é uma operação que consome um certo tempo dos navegadores. Em sites que utilizam CDN, por exemplo, é útil utilizar o prefetching de nomes de domínios comumente utilizados. Assim, quando algum arquivo de outro domínio é requisitado, o navegador já sabe o IP onde deve ir.
A utilização do DNS prefetching é similar ao do link prefetching, a diferença é que é usado o valor "dns-prefetch" no atributo rel do link, que deve apontar para um domínio, como neste exemplo:

    &lt;link rel="dns-prefetch" href="//www.exemplo.com" /&gt;