Cache HTTP Explicado: ETag, Cache-Control e CDNs
Por que seu site parece lento (e como o cache resolve isso)
Você otimizou suas imagens, minificou seu CSS e até atualizou seu servidor. No entanto, visitantes recorrentes ainda enfrentam tempos de carregamento lentos, e seu servidor de origem está consumindo largura de banda. O culpado? Cache HTTP ineficiente. Sem cabeçalhos de cache adequados, os navegadores baixam novamente os mesmos recursos a cada visita, e as CDNs não conseguem fazer seu trabalho de forma eficaz.
O cache HTTP é uma das otimizações de desempenho de maior alavancagem disponíveis. Ele reduz a latência, corta custos de largura de banda e alivia a carga nos servidores de origem. Neste guia, vamos detalhar os principais mecanismos: ETag, Cache-Control e como as CDNs se encaixam nesse cenário. Você aprenderá estratégias práticas para implementá-los corretamente.
Como funciona o cache HTTP: o panorama geral
Quando um navegador solicita um recurso, ele pode buscá-lo no servidor de origem ou servir uma cópia armazenada localmente. O cache HTTP define as regras para quando uma cópia armazenada é considerada válida e quando precisa ser revalidada.
Existem dois tipos principais de cache:
- Cache do navegador (privado): O navegador do usuário armazena recursos localmente. Isso beneficia um único usuário em várias páginas ou visitas.
- Cache compartilhado (CDN, proxy): Servidores intermediários armazenam recursos para vários usuários. Isso reduz a carga na sua origem e acelera a entrega globalmente.
Ambos dependem de cabeçalhos HTTP para decidir a validade e a revalidação. Os dois cabeçalhos mais importantes são Cache-Control e ETag.
Cache-Control: as regras de validade
Cache-Control é o cabeçalho principal para definir políticas de cache. É um cabeçalho baseado em diretivas que informa aos caches como tratar uma resposta.
Diretivas principais
- max-age: O número de segundos que uma resposta é considerada válida. Por exemplo,
Cache-Control: max-age=3600significa que a resposta é válida por 1 hora. - s-maxage: Como max-age, mas especificamente para caches compartilhados (CDNs). Substitui max-age para caches compartilhados.
- public: A resposta pode ser armazenada em cache por qualquer cache, incluindo os compartilhados.
- private: A resposta é destinada a um único usuário e não deve ser armazenada por caches compartilhados.
- no-cache: A resposta pode ser armazenada, mas deve ser revalidada com a origem antes de cada uso.
- no-store: A resposta não deve ser armazenada em nenhum cache. Use para dados sensíveis.
- must-revalidate: Uma vez obsoleta, o cache não deve usar a resposta sem revalidação.
- immutable: A resposta não mudará durante seu período de validade. Útil para recursos versionados.
Exemplo: Cache-Control: public, max-age=31536000, immutable é ideal para recursos estáticos com nomes de arquivo com hash.
ETag e requisições condicionais
Um ETag (Entity Tag) é um identificador para uma versão específica de um recurso. Quando um recurso muda, o ETag muda. Os navegadores usam ETags para fazer requisições condicionais: eles enviam o ETag armazenado em um cabeçalho If-None-Match. Se o recurso não mudou, o servidor responde com 304 Not Modified e sem corpo, economizando largura de banda.
Da mesma forma, Last-Modified funciona com If-Modified-Since, mas os ETags são mais precisos (podem detectar mudanças dentro do mesmo segundo).
Como gerar ETags
A maioria dos servidores web e frameworks gera ETags automaticamente. Por exemplo, no Express.js você pode habilitá-lo com app.set('etag', 'strong'). No Nginx, os ETags estão ativados por padrão para arquivos estáticos.
ETags fortes (por exemplo, "abc123") garantem identidade byte a byte. ETags fracos (por exemplo, W/"abc123") indicam equivalência semântica, não bytes exatos.
Cache de CDN: cache compartilhado em escala
CDNs (Content Delivery Networks) atuam como caches compartilhados distribuídos globalmente. Elas armazenam seu conteúdo em locais de borda, servindo-o aos usuários a partir de um ponto de presença próximo. Isso reduz a latência e alivia sua origem.
As CDNs respeitam os cabeçalhos Cache-Control, mas frequentemente têm sua própria configuração. Conceitos-chave:
- Cache de borda: O cache local da CDN. Ele armazena respostas com base em chaves de cache (geralmente URL + cabeçalhos como
Accept-Encoding). - Origin shield: Uma camada adicional de cache que reduz as requisições à sua origem.
- Invalidação de cache: As CDNs fornecem APIs para limpar conteúdo em cache quando você atualiza recursos.
Ao usar uma CDN, defina Cache-Control com s-maxage para controlar a validade do cache compartilhado separadamente do cache do navegador. Por exemplo: Cache-Control: public, max-age=600, s-maxage=3600 significa que os navegadores armazenam em cache por 10 minutos, mas a CDN armazena por 1 hora.
Comparação de cabeçalhos de cache
| Cabeçalho | Propósito | Exemplo |
|---|---|---|
Cache-Control |
Define regras de validade e cache | public, max-age=3600 |
ETag |
Identificador único para uma versão do recurso | "abc123" |
Last-Modified |
Data e hora da última modificação | Wed, 21 Oct 2025 07:28:00 GMT |
Expires |
Data de expiração absoluta legada | Wed, 21 Oct 2025 07:28:00 GMT |
Vary |
Especifica cabeçalhos que afetam o cache | Accept-Encoding |
Nota: Expires foi substituído por Cache-Control, mas ainda é usado por clientes mais antigos.
Estratégia prática de cache para aplicações web
Siga estes passos para implementar um cache eficaz:
- Impressão digital de recursos estáticos: Use nomes de arquivo com hash (por exemplo,
app.a1b2c3.js) e defina ummax-agelongo comimmutable. Quando o arquivo muda, o hash muda, invalidando o cache. - Defina Cache-Control apropriado para HTML: O HTML geralmente deve ser
no-cacheou ter ummax-agecurto para que os usuários recebam atualizações rapidamente. UseETagpara revalidação. - Use
Vary: Accept-Encoding: Se você serve versões comprimidas e não comprimidas, isso garante que os caches as armazenem separadamente. - Aproveite a CDN com s-maxage: Defina um
s-maxagemais longo para caches compartilhados para reduzir a carga na origem, mantendo o cache do navegador mais curto, se necessário. - Invalide com sabedoria: Use APIs de limpeza da CDN ao implantar atualizações críticas. Para recursos estáticos, a impressão digital evita a necessidade de limpeza.
- Monitore a taxa de acertos do cache: Use análises da CDN para garantir que seu cache seja eficaz. Uma taxa de acertos baixa significa cabeçalhos mal configurados.
Armadilhas comuns e como evitá-las
- Excesso de cache em HTML: Os usuários veem conteúdo desatualizado. Use
no-cacheou ummax-agecurto. - Cache insuficiente em recursos estáticos: Defina um
max-agelongo (por exemplo, 1 ano) com impressão digital. - Ignorar
Vary: Os caches podem servir conteúdo errado (por exemplo, gzip vs. simples). Sempre definaVary: Accept-Encoding. - Esquecer
privatepara dados específicos do usuário: Caches compartilhados podem vazar dados. UseCache-Control: privatepara respostas autenticadas. - Uso incorreto de
no-store: Isso impede todo o cache, o que pode prejudicar o desempenho. Use apenas para dados sensíveis.
Testando sua configuração de cache
Use as Ferramentas de Desenvolvedor do navegador (aba Rede) para inspecionar os cabeçalhos de resposta e ver se os recursos são servidos do cache (procure por "(from disk cache)" ou "(from memory cache)"). Para o comportamento da CDN, use curl -I para verificar cabeçalhos como X-Cache ou CF-Cache-Status. Ferramentas como WebPageTest podem visualizar o cache entre visitas.
Perguntas frequentes
Qual é a diferença entre ETag e Last-Modified?
ETag é um identificador opaco que muda quando o recurso muda, enquanto Last-Modified é um carimbo de data/hora. Os ETags são mais precisos porque podem detectar mudanças dentro do mesmo segundo e não dependem da sincronização de relógio.
Quando devo usar no-cache vs no-store?
Use no-cache quando quiser que o cache armazene a resposta, mas a revalide com a origem antes de cada uso. Use no-store para dados sensíveis que nunca devem ser gravados em disco ou memória por nenhum cache.
Como as CDNs lidam com a invalidação de cache?
As CDNs fornecem APIs de limpeza que permitem remover URLs específicas ou diretórios inteiros de seus caches de borda. Algumas também suportam limpezas suaves que marcam o conteúdo como obsoleto e revalidam na próxima requisição. A impressão digital de recursos geralmente é mais eficiente do que a limpeza.
Conclusão
Dominar o cache HTTP com ETag, Cache-Control e CDNs é essencial para construir aplicações web rápidas e escaláveis. Comece definindo cabeçalhos adequados para seus recursos estáticos e HTML, aproveite os caches compartilhados da CDN com s-maxage e sempre teste sua configuração. Pequenas mudanças nos cabeçalhos de cache podem levar a ganhos significativos de desempenho.
Precisa analisar rapidamente seus logs de servidor para ver as taxas de acertos do cache? Experimente nosso Analisador de Logs do Nginx para processar e visualizar seus logs de acesso.