Quando um service worker processa eventos fetch
, o navegador espera que o service worker forneça uma resposta. Embora a latência da solicitação de rede seja uma grande parte da espera, o navegador também pode precisar aguardar a inicialização do service worker e disparar callbacks de eventos fetch
.
O tempo de inicialização varia de acordo com o dispositivo e seus recursos, mas o tempo envolvido pode ser substancial, às vezes de até meio segundo quando a CPU está lenta ou funcionando em um estado limitado devido a condições do ambiente. O ganho de desempenho ao evitar a rede provavelmente vai compensar esse tempo de inicialização quando as respostas de navegação são disponibilizadas por uma instância Cache
. Para solicitações de navegação que vão para a rede, a introdução de um service worker pode criar um atraso perceptível.
Entrar no pré-carregamento de navegação
O pré-carregamento de navegação é um recurso do service worker que resolve o atraso causado pelo tempo de inicialização do service worker. Sem o pré-carregamento de navegação ativado, a inicialização do service worker e a solicitação de navegação que ele gerencia vão ocorrer consecutivamente:
Isso não é o ideal, mas é possível corrigi-lo ativando o pré-carregamento da navegação, o que garante que a inicialização do service worker e a solicitação de navegação ocorram simultaneamente:
Embora o pré-carregamento de navegação seja uma ótima otimização de desempenho para sites que usam service workers, ele não é um recurso que precisa ser ativado em todas as situações. Em particular, os sites que usam um shell do aplicativo pré-armazenado em cache não precisam do pré-carregamento de navegação, porque o cache exibe a solicitação de navegação para a marcação do shell do aplicativo sem qualquer latência de navegação. Nesses casos, a resposta pré-carregada será desperdiçada, o que não é muito bom.
O melhor momento para usar o pré-carregamento de navegação é quando um site não pode pré-armazenar em cache o HTML. Pense em sites em que as respostas de marcação são dinâmicas e variam de acordo com coisas como o estado de autenticação. As solicitações de navegação para esses casos podem usar uma estratégia que prioriza a rede (ou até mesmo uma apenas de rede). Por isso, o pré-carregamento de navegação pode fazer uma grande diferença.
Como usar o pré-carregamento de navegação no Workbox
É complicado usar o pré-carregamento de navegação diretamente em um service worker que não usa a tecnologia do Workbox. Primeiro, ele não é compatível com todos os navegadores. Em segundo lugar, pode ser difícil acertar. Aprenda a usá-la diretamente nesta ótima explicação de Jake Archibald (link em inglês).
O Workbox simplifica o uso do pré-carregamento de navegação, porque o método enable
do módulo workbox-navigation-preload
faz as verificações necessárias de suporte a recursos, além de criar o listener de eventos activate
para ativá-lo para você.
A partir daqui, os benefícios do pré-carregamento de navegação são alcançados em navegadores compatíveis usando o Workbox para processar solicitações de navegação usando um gerenciador de estratégia que prioriza a rede:
import * as navigationPreload from 'workbox-navigation-preload';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {registerRoute, NavigationRoute, Route} from 'workbox-routing';
import {precacheAndRoute} from 'workbox-precaching';
// Precache the manifest
precacheAndRoute(self.__WB_MANIFEST);
// Enable navigation preload
navigationPreload.enable();
// Create a new navigation route that uses the Network-first, falling back to
// cache strategy for navigation requests with its own cache. This route will be
// handled by navigation preload. The NetworkOnly strategy will work as well.
const navigationRoute = new NavigationRoute(new NetworkFirst({
cacheName: 'navigations'
}));
// Register the navigation route
registerRoute(navigationRoute);
// Create a route for image, script, or style requests that use a
// stale-while-revalidate strategy. This route will be unaffected
// by navigation preload.
const staticAssetsRoute = new Route(({request}) => {
return ['image', 'script', 'style'].includes(request.destination);
}, new StaleWhileRevalidate({
cacheName: 'static-assets'
}));
// Register the route handling static assets
registerRoute(staticAssetsRoute);
Quando o pré-carregamento de navegação está ativado, o Workbox responde às solicitações de navegação que usam as estratégias NetworkFirst
ou NetworkOnly
com a resposta pré-carregada.
Como saber se o pré-carregamento da navegação está funcionando?
Nos builds de desenvolvimento, o Workbox registra muito sobre o que ele faz. Se você quiser verificar se o pré-carregamento da navegação está funcionando no Workbox, abra o console em um navegador compatível durante uma solicitação de navegação. Uma mensagem de registro será exibida com as seguintes informações:
Por padrão, essa geração de registros não será exibida em builds de produção. Portanto, ela não será exibida quando você implantar o service worker na produção, mas é uma ótima maneira de verificar se o pré-carregamento de navegação está funcionando, entre outras coisas.
Como personalizar respostas pré-carregadas
Ao usar o pré-carregamento de navegação, pode haver cenários em que é necessário personalizar as respostas pré-carregadas em um back-end de aplicativo. Os service workers que transmitem conteúdo parcial da rede são um cenário em que isso pode ser útil.
Nesses casos, vale a pena saber que as solicitações de pré-carregamento são enviadas com um cabeçalho Service-Worker-Navigation-Preload
definido com um valor padrão de true
:
Service-Worker-Navigation-Preload: true
Em seguida, no back-end do aplicativo escolhido, verifique esse cabeçalho e modifique a resposta para atender às suas necessidades. Se o valor padrão do cabeçalho apresentar problemas por qualquer motivo, altere-o no contexto da janela. Saiba que qualquer trabalho que você fizer no servidor para ler esse cabeçalho depende de você e está fora do escopo do Workbox.
Conclusão
O pré-carregamento de navegação é difícil de acertar quando usado diretamente, mas esse trabalho árduo vale a pena para garantir que um service worker não impeça o navegador de fazer solicitações de navegação. Graças ao Workbox, você pode aproveitar o pré-carregamento da navegação com muito menos trabalho. Para mais detalhes sobre o módulo workbox-navigation-preload
, consulte a documentação de referência dele.