Performance é crucial para qualquer aplicação web moderna. Portanto, entender estratégias de cache no Next.js pode transformar completamente a experiência do usuário. Além disso, implementar cache corretamente reduz custos de infraestrutura e melhora o SEO. Neste guia, você vai aprender as principais estratégias de cache Next.js e como aplicá-las na prática.
O Que É Cache no Next.js?
Cache é como uma “memória rápida” da sua aplicação. Em outras palavras, é uma cópia temporária de dados armazenada para acesso instantâneo. Assim, quando um usuário visita sua página, ela carrega muito mais rápido.
Imagine um restaurante que prepara alguns pratos populares antecipadamente. Portanto, quando um cliente pede, o prato sai na hora. Consequentemente, o atendimento fica mais rápido. Da mesma forma, o Next.js “prepara” páginas antecipadamente para entregar rapidamente aos usuários.
O Next.js oferece várias camadas de cache: geração estática, revalidação incremental e cache de dados. Além disso, cada estratégia serve para cenários diferentes. Por exemplo, blogs usam regeneração, enquanto landing pages usam geração estática pura.
Static Site Generation (SSG)
SSG gera páginas HTML no momento do build. Assim, o servidor entrega arquivos prontos instantaneamente. Portanto, essa é a estratégia mais rápida possível.
Recomenda-se SSG quando o conteúdo muda pouco ou nada. Por exemplo, páginas institucionais, documentação e landing pages. Dessa forma, você obtém performance máxima com custo mínimo.
Veja a seguir a implementação básica:
// app/sobre/page.tsx
export default async function SobrePage() {
return (
<div>
<h1>Sobre Nós</h1>
<p>Conteúdo estático que raramente muda</p>
</div>
)
}
// Por padrão, componentes Server são SSG
// Página gerada uma vez no build
Além disso, com SSG você pré-renderiza rotas dinâmicas usando
generateStaticParams. Portanto, mesmo páginas dinâmicas ficam
estáticas:
// app/produto/[id]/page.tsx
export async function generateStaticParams() {
const produtos = await fetch('https://api.exemplo.com/produtos')
const data = await produtos.json()
return data.map((produto) => ({
id: produto.id.toString()
}))
}
export default async function ProdutoPage({ params }) {
const produto = await fetch(`https://api.exemplo.com/produtos/${params.id}`)
const data = await produto.json()
return <div>{data.nome}</div>
}
// Gera /produto/1, /produto/2, etc. no build
Incremental Static Regeneration (ISR)
ISR combina o melhor dos dois mundos: velocidade do estático com atualização do dinâmico. Em outras palavras, páginas são geradas estaticamente, mas regeneram automaticamente após um período.
Pense em um jornal digital que imprime edições a cada hora. Assim, leitores sempre veem conteúdo recente, mas não esperam pela geração. Consequentemente, você tem performance com dados atualizados.
Essa estratégia funciona bem para blogs, e-commerce e dashboards com dados que mudam periodicamente. Por exemplo, artigos de blog podem regenerar a cada hora. Dessa forma, novos posts aparecem sem rebuild completo.
Veja a seguir a implementação com revalidação temporal:
// app/blog/page.tsx
export const revalidate = 3600 // 1 hora em segundos
export default async function BlogPage() {
const posts = await fetch('https://api.exemplo.com/posts')
const data = await posts.json()
return (
<div>
{data.map(post => (
<article key={post.id}>
<h2>{post.titulo}</h2>
</article>
))}
</div>
)
}
// Página regenera automaticamente após 1 hora
// Primeira requisição após 1h serve cache antigo
// Segunda requisição já vê a versão atualizada
O ISR funciona em dois tempos. Primeiro, serve a página em cache. Depois, regenera em background. Portanto, usuários nunca esperam pela regeneração. Além disso, você controla a frequência de atualização com a configuração revalidate.
On-Demand Revalidation
Revalidação sob demanda invalida o cache quando você quiser. Por exemplo, quando publica um novo post ou atualiza um produto. Dessa forma, o cache atualiza imediatamente, não após um tempo.
Imagine uma loja que repõe prateleiras assim que recebe mercadoria nova. Consequentemente, clientes sempre veem os produtos mais recentes. Similarmente, revalidação sob demanda atualiza o cache instantaneamente.
A seguir, veja como criar uma API Route para revalidação:
// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from 'next/cache'
import { NextRequest, NextResponse } from 'next/server'
export async function POST(request: NextRequest) {
const body = await request.json()
const { secret, path, tag } = body
// Validar token de segurança
if (secret !== process.env.REVALIDATE_SECRET) {
return NextResponse.json({ error: 'Token inválido' }, { status: 401 })
}
try {
// Revalidar caminho específico
if (path) {
revalidatePath(path)
return NextResponse.json({ revalidated: true, path })
}
// Ou revalidar por tag
if (tag) {
revalidateTag(tag)
return NextResponse.json({ revalidated: true, tag })
}
return NextResponse.json({ error: 'Path ou tag necessário' }, { status: 400 })
} catch (error) {
return NextResponse.json({ error: 'Erro ao revalidar' }, { status: 500 })
}
}
Em seguida, veja como chamar a API de revalidação:
// Chamada manual para revalidar
fetch('https://seusite.com/api/revalidate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.REVALIDATE_SECRET,
path: '/blog'
})
})
// Ou revalidar por tag
fetch('https://seusite.com/api/revalidate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.REVALIDATE_SECRET,
tag: 'posts'
})
})
// Útil em webhooks de CMS headless, actions do GitHub,
// ou qualquer automação que detecte mudanças de conteúdo
Aplique revalidação sob demanda com CMS headless, e-commerce e painéis admin. Portanto, quando atualizar dados no backend, o cache atualiza instantaneamente no frontend. Além disso, você combina performance de cache com dados sempre atualizados. A função revalidatePath e revalidateTag facilitam essa implementação.
Cache de Dados com Fetch
Next.js estende o fetch nativo com cache automático. Dessa forma,
você controla como cada requisição é cacheada. Consequentemente, otimiza cada
chamada de API individualmente.
A documentação oficial do Next.js explica detalhadamente as opções de cache. Portanto, consulte para casos avançados.
Abaixo estão as principais opções de cache no fetch:
// Cache padrão - armazena indefinidamente
const dados1 = await fetch('https://api.exemplo.com/dados', {
cache: 'force-cache' // Padrão no Next.js 14+
})
// Sem cache - sempre busca dados frescos
const dados2 = await fetch('https://api.exemplo.com/dados', {
cache: 'no-store' // Útil para dados em tempo real
})
// Cache com revalidação temporal
const dados3 = await fetch('https://api.exemplo.com/dados', {
next: { revalidate: 60 } // Revalida a cada 60 segundos
})
// Cache com tags para revalidação seletiva
const dados4 = await fetch('https://api.exemplo.com/posts', {
next: { tags: ['posts'] }
})
// Depois, invalida apenas esse cache:
// revalidateTag('posts')
Finalmente, veja um exemplo prático combinando estratégias:
// app/dashboard/page.tsx
export const revalidate = 300 // 5 minutos
export default async function DashboardPage() {
// Dados de usuário - sempre frescos
const usuario = await fetch('https://api.exemplo.com/usuario', {
cache: 'no-store'
})
// Estatísticas - cache de 5 minutos
const stats = await fetch('https://api.exemplo.com/stats', {
next: { revalidate: 300 }
})
// Configurações - cache permanente
const config = await fetch('https://api.exemplo.com/config', {
cache: 'force-cache'
})
const [usuarioData, statsData, configData] = await Promise.all([
usuario.json(),
stats.json(),
config.json()
])
return (
<div>
<h1>Olá, {usuarioData.nome}</h1>
<p>Vendas hoje: {statsData.vendas}</p>
</div>
)
}
Escolhendo a Estratégia Certa
Cada projeto tem necessidades diferentes. Portanto, escolha a estratégia baseado em frequência de atualização e criticidade dos dados.
SSG é ideal quando:
- Conteúdo raramente muda (institucional, documentação)
- Performance é prioridade máxima
- Você quer custos mínimos de servidor
Por outro lado, escolha ISR quando:
- Conteúdo atualiza periodicamente (blogs, notícias)
- Você quer balance entre performance e atualização
- Tem muitas páginas dinâmicas
Já a revalidação sob demanda funciona melhor quando:
- Usa CMS headless ou sistema de gestão de conteúdo
- Precisa atualizar cache imediatamente após mudanças
- Quer controle total sobre invalidação de cache
Finalmente, no-store é necessário quando:
- Dados mudam constantemente (tempo real)
- Informações personalizadas por usuário
- Dados sensíveis que não devem ser cacheados
Na prática, você provavelmente vai combinar estratégias. Por exemplo, ISR na listagem de posts com revalidação sob demanda. Assim, otimiza performance enquanto mantém conteúdo atualizado.
Conclusão
Dominar estratégias de cache no Next.js é essencial para criar aplicações rápidas e eficientes. Portanto, comece identificando quais páginas mudam com frequência. Em seguida, aplique a estratégia adequada para cada caso.
Lembre-se: cache bem implementado melhora performance, reduz custos e aumenta satisfação do usuário. Além disso, o Next.js facilita com APIs simples e intuitivas. Consequentemente, você implementa cache avançado com poucas linhas de código.
Primeiro, comece testando ISR em uma página de blog. Assim, você experimenta
os benefícios sem complexidade. Em seguida, adicione revalidação sob demanda
para controle total. Por fim, otimize cada requisição com as opções de
fetch.
Quer aprender mais sobre React e boas práticas? Confira nosso guia sobre princípios SOLID aplicados ao React e descubra como escrever código mais limpo e sustentável em suas aplicações Next.js.
- 【Teclado com Conexão TRIPLO】O teclado gamer X98pro para PC suporta Bluetooth 5.0, conexão sem fio de 2,4 GHz e conexão c…
- 【Tela LED colorida e botão CNC】A tela LED de matriz de 1,5 polegada permite a visualização intuitiva das informações de …
- 【Interruptor Hot-Swappable e Personalizável】O teclado gamer possui um assento de interruptor hot-swappable, compatível c…

Leave a Reply