3

SSR vs CSR: Quando Cada Abordagem Faz Sentido

O custo real de escolher errado

Uma página de marketing renderizada inteiramente no client faz o Googlebot indexar um <div id="root"></div> vazio. Uma dashboard administrativa renderizada no servidor força o backend a montar HTML complexo a cada request, desperdiçando CPU em conteúdo que nenhum crawler vai visitar. As duas decisões são erradas, mas pelos motivos opostos.

A escolha entre SSR e CSR não é filosófica. É uma decisão de engenharia que depende de três variáveis concretas: quem consome a página (crawler, usuário logado, visitante anônimo), com que frequência o conteúdo muda, e qual é o budget de infraestrutura disponível.

Como SSR e CSR funcionam por baixo

No CSR, o servidor entrega um HTML mínimo com um bundle JavaScript. O navegador baixa, parseia e executa esse bundle, que então faz fetch de dados e monta o DOM. O tempo até o usuário ver conteúdo depende do tamanho do bundle, da velocidade da conexão e da potência do dispositivo.

No SSR, o servidor executa o componente React (ou equivalente), gera o HTML completo e envia ao navegador. O usuário vê conteúdo antes de qualquer JavaScript executar. Depois, o processo de hydration conecta os event handlers ao HTML já renderizado.

// next.config.ts — configuração mínima do Next.js App Router
// O App Router usa SSR por padrão para Server Components
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  reactStrictMode: true,
  // poweredByHeader desabilitado para não expor stack ao crawler
  poweredByHeader: false,
};

export default nextConfig;

A diferença prática: no SSR, o servidor paga o custo de CPU para renderizar. No CSR, o dispositivo do usuário paga esse custo. Essa transferência de trabalho é o trade-off central.

Matriz de decisão: SSR, CSR ou nenhum dos dois

Antes de comparar código, a decisão precisa de critérios explícitos. A tabela abaixo cobre os cenários mais comuns.

CritérioSSR faz sentidoCSR faz sentidoConsidere SSG/ISR
SEO é requisito de negócioSim: crawler recebe HTML completoNão: crawler vê HTML vazio ou parcialSim, se conteúdo muda pouco
Conteúdo personalizado por usuárioSim, mas com custo de CPU por requestSim: dados carregados após autenticaçãoNão se aplica
Time to First Contentful PaintMenor: HTML chega prontoMaior: depende do bundle + fetchMenor ainda: HTML pré-gerado
Carga no servidorAlta: renderiza a cada requestBaixa: serve arquivos estáticosMínima: CDN serve cache
Interatividade pesada (editor, canvas)Não compensa: hydration é custosaSim: toda lógica roda no clientNão se aplica
Dados mudam a cada segundoSim, com streaming ou cache curtoSim, via WebSocket ou pollingNão: cache invalida rápido demais
Budget de infra limitadoCuidado: CPU escala com tráfegoSim: CDN + API separada é baratoSim: build-time, sem runtime

A coluna "Considere SSG/ISR" existe porque SSR e CSR não são as únicas opções. Static Site Generation (SSG) e Incremental Static Regeneration (ISR) resolvem cenários que nenhum dos dois cobre bem.

SSR na prática: página de produto com dados dinâmicos

Um e-commerce precisa que o Googlebot indexe título, preço e descrição. O conteúdo muda quando o estoque atualiza. SSR resolve isso.

// app/products/[slug]/page.tsx — Server Component (Next.js App Router)
// Server Components são SSR por padrão: sem "use client", sem useState
import { notFound } from "next/navigation";
import { getProductBySlug } from "@/lib/products";
import { AddToCartButton } from "@/components/add-to-cart-button";

interface ProductPageProps {
  params: Promise<{ slug: string }>;
}

export default async function ProductPage({ params }: ProductPageProps) {
  const { slug } = await params;
  const product = await getProductBySlug(slug);

  if (!product) {
    notFound();
  }

  return (
    <article>
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      {/* Preço rende

---

Leia o artigo completo em [https://www.vivodecodigo.com.br/nextjs/ssr-vs-csr-quando-usar-server-side-client-side-rendering](https://www.vivodecodigo.com.br/nextjs/ssr-vs-csr-quando-usar-server-side-client-side-rendering)
Carregando publicação patrocinada...