Aquela famosa citação "Existem apenas duas coisas difíceis na Ciência da Computação: invalidação de cache e nomenclatura de coisas" reflete a realidade. O cache é, simultaneamente, a otimização de desempenho mais impactante e a mais complexa de implementar corretamente. Se bem feito, o cache pode tornar seu site 10 a 100 vezes mais rápido. Se mal executado, ele serve dados desatualizados aos seus usuários.
As Camadas do Cache
Uma requisição web típica passa por diversas camadas de cache:
- Cache do Navegador: O mais próximo do usuário. Armazena recursos localmente no dispositivo dele.
- Cache de CDN: Servidores de borda distribuídos globalmente. Serve o conteúdo da localização geográfica mais próxima.
- Cache de Proxy Reverso: Nginx, Varnish ou Cloudflare posicionados na frente do seu servidor de aplicação.
- Cache da Aplicação: Armazenamentos em memória como Redis ou Memcached para resultados de consultas ao banco de dados, respostas de API e valores computados.
- Cache do Banco de Dados: Cache de consulta e pool de buffer embutidos no motor do banco de dados.
Headers de Cache do Navegador
# Ativos estáticos (CSS, JS, imagens) — cache agressivo Cache-Control: public, max-age=31536000, immutable # Páginas HTML — não cachear, sempre revalidar Cache-Control: no-cache # Respostas de API — cachear por 5 minutos Cache-Control: private, max-age=300 # Dados sensíveis — nunca cachear Cache-Control: no-store
Diretivas Chave
public— Pode ser cacheado por navegadores E caches intermediários (CDNs, proxies).private— Apenas o navegador do usuário pode cacheá-lo (não CDNs).max-age=N— Cachear por N segundos.no-cache— Cachear, mas sempre revalidar com o servidor antes de usar.no-store— Não cachear de forma alguma. Use para dados sensíveis.immutable— O conteúdo nunca mudará (usado com nomes de arquivo com hash).
Quebra de Cache com Nomes de Arquivo Fingerprinted
A estratégia ideal de cache para ativos estáticos: dê aos arquivos um hash único no nome do arquivo e cacheie-os para sempre.
<!-- Em vez disso (pesadelo de invalidação de cache): -->
<link rel="stylesheet" href="/pt/css/style.css">
<!-- Use isto (infinitamente cacheável): -->
<link rel="stylesheet" href="/pt/css/style.a3f9b2c1.css">
<!-- Quando o CSS muda, o hash muda, então o navegador
busca o novo arquivo automaticamente -->
Ferramentas de build como Vite, Webpack e esbuild geram esses nomes de arquivo fingerprinted automaticamente.
Cache em CDN
Uma CDN (Content Delivery Network) armazena seu conteúdo em servidores de borda ao redor do mundo. Quando um usuário em Tóquio solicita sua imagem, ela é servida de um servidor em Tóquio, em vez do seu servidor de origem em Londres.
- Ativos estáticos: Cache na borda da CDN com
max-agelongo + nomes de arquivo fingerprinted. - Páginas HTML: Cachear com TTL curto (ex: 60 segundos) ou usar
stale-while-revalidate. - Respostas de API: Cachear requisições GET para dados públicos, nunca cachear POST/PUT/DELETE.
Cache no Lado do Servidor com Redis
import Redis from 'ioredis';
const redis = new Redis();
async function getUser(userId) {
const cacheKey = `user:${userId}`;
// 1. Verifique o cache primeiro
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
// 2. Cache miss — consulte o banco de dados
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
// 3. Armazene no cache (expire em 5 minutos)
await redis.set(cacheKey, JSON.stringify(user), 'EX', 300);
return user;
}
// Invalide na atualização
async function updateUser(userId, data) {
await db.query('UPDATE users SET ... WHERE id = $1', [userId]);
await redis.del(`user:${userId}`); // Limpe o cache
}
Estratégias de Invalidação de Cache
- TTL (Time-To-Live): O cache expira após um tempo fixo. Simples, mas pode servir dados desatualizados.
- Write-Through: Atualize o cache sempre que atualizar o banco de dados. Consistente, mas adiciona latência de escrita.
- Write-Behind: Atualize o cache imediatamente, envie para o banco de dados assincronamente. Rápido, mas arriscado.
- Cache-Aside: A aplicação gerencia o cache manualmente (o exemplo do Redis acima). Padrão mais comum.
- Orientado a Eventos: Mudanças no banco de dados emitem eventos que invalidam caches relevantes. Mais robusto para sistemas distribuídos.
Experimente Nossas Ferramentas de Desempenho Gratuitas
Minifique seu CSS, JavaScript e HTML para reduzir o tamanho dos arquivos.