Pré-busca, pré-renderização e pré-armazenamento em cache do service worker

Nos últimos módulos, você descobriu conceitos como adiar o carregamento de JavaScript e imagens de carregamento lento e elementos <iframe>. Adiar o carregamento de recursos diminui o uso da rede e da CPU durante o carregamento de página inicial, fazendo o download de recursos no ponto em que são necessários, em vez de carregá-los antecipadamente, onde eles podem não ser usados. Isso pode melhorar o tempo de carregamento da página inicial, mas as interações subsequentes poderão gerar atraso se os recursos necessários para alimentá-las ainda não estiverem carregados no momento em que ocorrem.

Por exemplo, se uma página tiver um seletor de data personalizado, você poderá adiar os recursos dele até que o usuário interaja com o elemento. No entanto, carregar os recursos do seletor de data sob demanda pode resultar em um atraso, talvez leve, mas talvez não, dependendo da conexão de rede do usuário, dos recursos do dispositivo ou de ambos até que os recursos sejam transferidos por download, analisados e disponíveis para execução.

É um equilíbrio um pouco complicado. Você não quer desperdiçar largura de banda carregando recursos que podem não ser usados, mas atrasar interações e carregamentos de página subsequentes também pode não ser o ideal. Felizmente, existem várias ferramentas que podem ser usadas para encontrar um melhor equilíbrio entre esses dois extremos. Este módulo aborda algumas técnicas que podem ser usadas para chegar lá, como pré-busca de recursos, pré-renderização de páginas inteiras e pré-armazenamento em cache de recursos usando um service worker.

Buscar recursos necessários em um futuro próximo com baixa prioridade

É possível buscar preventivamente recursos, incluindo imagens, folhas de estilo ou recursos JavaScript, usando a dica <link rel="prefetch">. A dica prefetch informa ao navegador que um recurso provavelmente será necessário em um futuro próximo.

Quando uma dica prefetch é especificada, o navegador pode iniciar uma solicitação para esse recurso com a menor prioridade para evitar conflitos com os recursos necessários para a página atual.

A pré-busca de recursos pode melhorar a experiência do usuário, já que ele não precisa aguardar o download dos recursos necessários em um futuro próximo, já que eles podem ser recuperados instantaneamente do cache de disco quando necessário.

<head>
  <!-- ... -->
  <link rel="prefetch" as="script" href="/date-picker.js">
  <link rel="prefetch" as="style" href="/date-picker.css">
  <!-- ... -->
</head>

O snippet HTML anterior informa ao navegador que ele pode fazer a pré-busca de date-picker.js e date-picker.css quando estiver inativo. Também é possível fazer a pré-busca de recursos dinamicamente à medida que o usuário interage com a página em JavaScript.

O prefetch é compatível com todos os navegadores modernos, exceto o Safari, onde está disponível por trás de uma flag. Se você tiver uma forte necessidade de carregar recursos para seu site antecipadamente de uma maneira que funcione em todos os navegadores e estiver usando um service worker, leia a seção mais adiante neste módulo sobre como armazenar recursos em cache usando um service worker.

Faça uma pré-busca de páginas para acelerar navegações futuras

Também é possível fazer a pré-busca de uma página e de todos os sub-recursos dela especificando o atributo as="document" ao apontar para um documento HTML:

<link rel="prefetch" href="/page" as="document">

Quando o navegador está inativo, ele pode iniciar uma solicitação de baixa prioridade para o /page.

Em navegadores baseados no Chromium, é possível fazer a pré-busca de documentos usando a API Speculation Rules. As regras de especulação são definidas como um objeto JSON incluído no HTML da página ou adicionado dinamicamente por JavaScript:

<script type="speculationrules">
{
  "prefetch": [{
    "source": "list",
    "urls": ["/page-a", "/page-b"]
  }]
}
</script>

O objeto JSON descreve uma ou mais ações, atualmente compatíveis apenas com prefetch e prerender, e uma lista de URLs associados a essa ação. No snippet HTML anterior, o navegador é instruído a fazer a pré-busca de /page-a e /page-b. Assim como o <link rel="prefetch">, as regras de especulação são uma dica que o navegador pode ignorar em determinadas circunstâncias.

Bibliotecas como o Quicklink melhoram a navegação nas páginas ao pré-buscar dinamicamente ou pré-renderizar links quando eles estão visíveis na janela de visualização do usuário. Isso aumenta a probabilidade de o usuário acessar essa página, em comparação com a pré-busca de todos os links na página.

Pré-renderizar páginas

Além de pré-buscar recursos, também é possível sugerir ao navegador para pré-renderizar uma página antes de o usuário navegar até ela. Isso pode proporcionar carregamentos de página quase instantâneos, já que a página e os recursos dela são buscados e processados em segundo plano. Quando o usuário navega para a página, ela é colocada em primeiro plano.

A pré-renderização é compatível com a API Speculation Rules:

<script type="speculationrules">
{
  "prerender": [
    {
      "source": "list",
      "urls": ["/page-a", "page-b"]
    }
  ]
}
</script>

Pré-busca e pré-renderização de demonstrações

Pré-armazenamento em cache do service worker

Também é possível fazer a pré-busca de recursos de maneira especulativa usando um service worker. O pré-armazenamento em cache do service worker pode buscar e salvar recursos usando a API Cache, permitindo que o navegador atenda à solicitação usando a API Cache sem acessar a rede. O pré-armazenamento em cache do service worker usa uma estratégia muito eficaz de armazenamento em cache, conhecida como estratégia somente em cache. Esse padrão é altamente eficaz porque, uma vez que os recursos são colocados no cache do service worker, eles são buscados quase instantaneamente mediante solicitação.

Mostra o fluxo de armazenamento em cache do service worker da página para o service worker e o cache.
A estratégia somente cache só recupera recursos qualificados da rede durante a instalação do service worker. Depois de instalados, os recursos armazenados em cache só são recuperados do cache do service worker.

Para pré-armazenar recursos em cache com um service worker, use o Workbox. No entanto, se preferir, escreva seu próprio código para armazenar em cache um conjunto predeterminado de arquivos. De qualquer forma, se você decidir usar um service worker para pré-armazenar recursos em cache, é importante saber que o pré-armazenamento em cache acontece quando o service worker está instalado. Após a instalação, os recursos pré-armazenados em cache ficam disponíveis para recuperação em qualquer página que o service worker controla no seu site.

O Workbox usa um manifesto de pré-cache para determinar quais recursos precisam ser armazenados em cache. Um manifesto de pré-cache é uma lista de arquivos e informações de controle de versões que serve como a "fonte da verdade" para os recursos que vão ser armazenados em pré-cache.

[{  
    url: 'script.ffaa4455.js',
    revision: null
}, {
    url: '/index.html',
    revision: '518747aa'
}]

O código anterior é um exemplo de manifesto que inclui dois arquivos: script.ffaa4455.js e /index.html. Se um recurso contiver informações de versão no próprio arquivo (conhecido como hash de arquivo), a propriedade revision poderá ser deixada como null, porque o arquivo já tem controle de versão (por exemplo, ffaa4455 para o recurso script.ffaa4455.js no código anterior). Para recursos sem controle de versão, uma revisão pode ser gerada para eles no tempo de build.

Depois de configurado, um service worker pode ser usado para pré-armazenar em cache as páginas estáticas ou os sub-recursos delas para acelerar as navegações subsequentes nas páginas.

workbox.precaching.precacheAndRoute([
  '/styles/product-page.ac29.css',
  '/styles/product-page.39a1.js',
]);

Por exemplo, em uma página de informações do produto de e-commerce, um service worker pode ser usado para pré-armazenar em cache o CSS e o JavaScript necessários para renderizar a página de detalhes do produto, fazendo com que a navegação até essa página pareça muito mais rápida. No exemplo anterior, product-page.ac29.css e product-page.39a1.js são armazenados previamente em cache. O método precacheAndRoute disponível em workbox-precaching registra automaticamente os gerenciadores necessários para garantir que os recursos pré-armazenados em cache sejam buscados na API do service worker sempre que necessário.

Como os service workers têm ampla compatibilidade, é possível usar o pré-armazenamento em cache de service worker em qualquer navegador moderno que a situação exigir.

testar seus conhecimentos

Em que prioridade ocorre uma dica prefetch?

Alto.
Tente novamente.
Média.
Tente novamente.
Baixas.
Correto.

Qual é a diferença entre a pré-busca e a pré-renderização de uma página?

Enquanto a pré-busca e a pré-renderização de uma página recebem uma página e todos os sub-recursos dela, a pré-busca apenas recupera a página e todos os recursos dela, enquanto uma pré-renderização vai um passo além, renderizando toda a página em segundo plano até que o usuário navegue até ela.
Correto.
Eles são quase iguais. Apenas uma pré-renderização recebe todos os sub-recursos de uma página, a pré-busca não.
Tente novamente.

O cache do service worker e o cache HTTP são os mesmos.

Verdadeiro
Tente novamente.
Falso
Correto.

A seguir: uma visão geral dos Web workers

Agora que você sabe como a pré-busca, a pré-renderização e o pré-armazenamento em cache do service worker podem ser benéficos para acelerar a navegação em páginas futuras, é possível tomar decisões informadas sobre como isso pode ser benéfico para seu site e os usuários.

Em seguida, apresentamos uma visão geral dos Web workers e como eles podem tirar o trabalho caro da linha de execução principal e dar à linha de execução principal mais espaço para interações do usuário. Se você já se perguntou o que poderia fazer para dar mais espaço para a linha de execução principal, os próximos dois módulos valem a pena!