Guia Prático: Caching & Service Workers para Web Performance

Quando pensamos em performanceDebugging e Ferramentas de Desenvolvimento do NavegadorDebugging e Ferramentas de Desenvolvimento do NavegadorAprenda a depurar código JavaScript com as Ferramentas do Navegador. Use console, breakpoints e debugger para solucionar bugs de forma prática. e otimização de aplicações web, não podemos deixar de abordar o tema de caching. O cache possibilita o armazenamento de recursos localmente, reduzindo requisições desnecessárias e proporcionando um tempo de carregamento mais rápido da página para o usuário. Além disso, com o auxílio de Service Workers, podemos criar experiências offline e tornar a aplicação mais eficiente e responsivaResponsividade com HTML: Viewport e `<picture>`Responsividade com HTML: Viewport e `<picture>`Descubra como usar a meta viewport e o elemento picture para imagens responsivas, garantindo desempenho, usabilidade e SEO de qualidade.. Neste tutorial, vamos explorar as principais técnicas de caching, como funcionam os Service Workers e como combinar esses recursos para alavancar o desempenhoDebugging e Ferramentas de Desenvolvimento do NavegadorDebugging e Ferramentas de Desenvolvimento do NavegadorAprenda a depurar código JavaScript com as Ferramentas do Navegador. Use console, breakpoints e debugger para solucionar bugs de forma prática. da sua aplicação web.

Introdução ao Caching em Aplicações Web🔗

O caching em aplicações web consiste em armazenar localmente determinados arquivos ou dados para que, em acessos futuros, eles sejam carregados diretamente de um repositório local (por exemplo, o cache do navegador ou o cache gerenciado pelo Service Worker), em vez de fazer o download novamente do servidor. Isso contribui para:

  • Reduzir o tempo de carregamento das páginas.
  • Economizar banda de rede e recursos do servidor.
  • Melhorar a experiência do usuário em conexões lentas ou instáveis.

É fundamental definir estratégias inteligentes de cache para garantir que as informações sejam atualizadas corretamente, evitando que os usuários recebam dados antigos.

Breve Visão Geral de Service Workers🔗

Os Service Workers são scripts que rodam em background no navegador, separados do documento principal. Eles permitem interceptar requisições e gerenciar o cache de forma avançada. Entre seus principais benefícios estão:

Para usar um Service Worker, você deve registrá-lo no seu código JavaScriptIntrodução ao JavaScript e Configuração do AmbienteIntrodução ao JavaScript e Configuração do AmbienteDescubra neste tutorial narrativo como configurar seu ambiente de desenvolvimento e começar a programar em JavaScript de maneira prática e eficiente., geralmente no arquivo principal da aplicação.

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js')
    .then((registration) => {
      console.log('Service Worker registrado com sucesso:', registration);
    })
    .catch((error) => {
      console.error('Falha ao registrar o Service Worker:', error);
    });
}

Fluxo de Registro e Instalação🔗

Quando um Service Worker é registrado, o navegador faz o download do arquivo e, se for a primeira vez ou se houve alguma atualização, passa pelos seguintes eventosEventos no JavaScript: onClick, onChange e maisEventos no JavaScript: onClick, onChange e maisDescubra como os eventos em JavaScript, como onClick e onChange, possibilitam interações dinâmicas e melhoram a experiência do usuário em páginas web.:

1. install: Momento em que o Service Worker é instalado. Normalmente, é aqui que se faz o pré-cache de recursos estáticosPosicionamento: static, relative, absolute, fixed, stickyPosicionamento: static, relative, absolute, fixed, stickyDescubra como usar os métodos de posicionamento CSS, de static a sticky, para criar layouts interativos, precisos e eficazes..

2. activate: Após a instalação, ocorre a ativação. Nesta fase, é comum limpar caches antigos e garantir que a nova versão do Service Worker assuma o controle.

3. fetchConsumindo APIs com Fetch e AxiosConsumindo APIs com Fetch e AxiosDescubra como integrar APIs com Fetch e Axios em JavaScript. Aprenda a fazer requisições HTTP, tratar erros e usar métodos GET e POST com exemplos práticos.: O Service Worker intercepta toda requisição feita pela aplicação. É nesse passo que definimos a lógica de cache.

Estratégias de Caching🔗

Existem diversas estratégias para servir arquivos e dados em uma aplicação. Conhecer as principais ajuda você a tomar decisões mais assertivas sobre quando e como buscar os recursos via rede ou via cache.

EstratégiaDescriçãoExemplo de Uso
Cache FirstBusca primeiro no cache e, se não encontrar, faz requisição à rede.Arquivos que raramente mudam (CSS e bibliotecas).
Network FirstTenta obter o arquivo da rede e, se não for possível, recorre ao cache.Recursos que precisam estar atualizados (JSON dinâmico).
Stale-While-RevalidateRetorna o arquivo do cache imediatamente, mas faz uma atualização em segundo plano para ter uma versão mais atualizada no próximo acesso.Combinação equilibrada entre desempenho e atualização.
Cache OnlySempre obtém o recurso do cache e nunca faz requisição de rede.Arquivos completamente estáticos, sem necessidade de atualização.
Network OnlySempre faz a requisição à rede, ignorando qualquer cache local.Conteúdo extremamente dinâmico e sensível a mudanças.

Exemplo de Implementação: Stale-While-Revalidate

Uma das estratégias mais populares é o Stale-WhileEstruturas de Controle: if, switch e loopsEstruturas de Controle: if, switch e loopsAprenda as estruturas de controle em JavaScript, como if/else, switch e loops, com exemplos claros e didáticos para otimizar seu código e lógica de programação.-Revalidate, pois equilibra desempenhoDebugging e Ferramentas de Desenvolvimento do NavegadorDebugging e Ferramentas de Desenvolvimento do NavegadorAprenda a depurar código JavaScript com as Ferramentas do Navegador. Use console, breakpoints e debugger para solucionar bugs de forma prática. e atualização dos dados. Segue um exemplo simplificado para interceptar requisições:

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.open('minha-app-cache').then((cache) => {
      return cache.match(event.request).then((response) => {
        const fetchPromise = fetch(event.request).then((networkResponse) => {
          // Atualiza o cache com a versão mais recente
          cache.put(event.request, networkResponse.clone());
          return networkResponse;
        });
        // Caso exista algo em cache, retorna imediatamente
        // enquanto a atualização é feita em segundo plano
        return response || fetchPromise;
      });
    })
  );
});

Neste fluxo:

1. Verificamos se existe uma resposta no cache.

2. Solicitamos a versão mais recente da rede em segundo plano.

3. Caso exista algo em cache, retornamos imediatamente ao usuário.

4. Atualizamos o cache para a próxima visita.

Lidando com Atualizações e Invalidação de Cache🔗

A invalidação do cache é crucial para evitar problemas com dados desatualizados. Quando você lança uma nova versão de sua aplicação, é recomendável usar:

  • Versões diferentes de cache: Alterar o nome do cache (por exemplo, minha-app-cache-v2).
  • Remover caches antigos na fase activate do seu Service Worker. Isso garante que usuários não fiquem com recursos antigos indefinidamente.

Exemplo de como limpar caches obsoletos:

self.addEventListener('activate', (event) => {
  const cacheWhitelist = ['minha-app-cache-v2'];
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames.map((cacheName) => {
          if (!cacheWhitelist.includes(cacheName)) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Boas Práticas🔗

1. Defina cabeçalhosFormatação de Texto: `<p>`, `<h1>-<h6>`, `<strong>`, `<em>`Formatação de Texto: `<p>`, `<h1>-<h6>`, `<strong>`, `<em>`Aprenda a formatar textos em HTML com tags de parágrafo, títulos e destaques, organizando seu conteúdo e garantindo semântica. de cache adequados: Mesmo com Service Workers, é uma boa prática configurar corretamente os cabeçalhosFormatação de Texto: `<p>`, `<h1>-<h6>`, `<strong>`, `<em>`Formatação de Texto: `<p>`, `<h1>-<h6>`, `<strong>`, `<em>`Aprenda a formatar textos em HTML com tags de parágrafo, títulos e destaques, organizando seu conteúdo e garantindo semântica. Cache-Control e ETag no servidor.

2. Agrupe recursos estáticosPosicionamento: static, relative, absolute, fixed, stickyPosicionamento: static, relative, absolute, fixed, stickyDescubra como usar os métodos de posicionamento CSS, de static a sticky, para criar layouts interativos, precisos e eficazes.: Combine ou minimize arquivos ao máximo para reduzir requisições e simplificar o processo de cache.

3. Mantenha a acessibilidadeInserindo Imagens: `<img>`, Formatos, `alt` e `title`Inserindo Imagens: `<img>`, Formatos, `alt` e `title`Aprenda a inserir imagens em HTML utilizando a tag <img> com foco em acessibilidade e performance, explorando atributos, formatos e melhores práticas. offline: Garanta que o usuário tenha ao menos parte da aplicação funcionando sem conexão, fornecendo uma página de fallback ou funcionalidades limitadas.

4. Inválido ou expirado?: Use versões diferentes para indicar ao navegador quando um recurso precisa ser baixado novamente.

5. Monitoramento e análise: Utilize ferramentas de análise de performanceDebugging e Ferramentas de Desenvolvimento do NavegadorDebugging e Ferramentas de Desenvolvimento do NavegadorAprenda a depurar código JavaScript com as Ferramentas do Navegador. Use console, breakpoints e debugger para solucionar bugs de forma prática. para identificar gargalos na aplicação e adequar suas estratégias de cache.

Conclusão🔗

O uso de caching e Service Workers é uma das melhores maneiras de proporcionar maior desempenhoDebugging e Ferramentas de Desenvolvimento do NavegadorDebugging e Ferramentas de Desenvolvimento do NavegadorAprenda a depurar código JavaScript com as Ferramentas do Navegador. Use console, breakpoints e debugger para solucionar bugs de forma prática. e disponibilidade para as aplicações web, possibilitando reduções significativas no tempo de carregamento e na quantidade de dados trafegados. Combinando estratégias adequadas de cache e atualização de arquivos, você consegue manter o conteúdo sempre acessível, rápido e eficiente, contribuindo para uma experiência de uso mais satisfatória.

Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.

Referências🔗

  • Documentação oficial do MDN - Essa referência é útil pois o MDN possui uma ampla documentação sobre Service Workers, caching e boas práticas de desenvolvimento web, tópicos centrais deste tutorial: developer.mozilla.org/pt-BR/docs/Web/JavaScript

Compartilhar artigo

Artigos Relacionados