SSR vs. CSR vs. SSG é uma comparação de estratégias de renderização por onde e quando o HTML é gerado: no build, no servidor ou no navegador. Esse único eixo — onde e quando — determina SEO, performance, frescor dos dados e custo; todo o resto é consequência dele. E o esclarecimento de engenheiro de backend que os guias de frontend enterram: renderização é uma preocupação do frontend; os dados são do backend. As três estratégias chamam a mesma API; elas diferem apenas no momento em que a chamam.
Principais pontos
| Pergunta | Resposta |
|---|---|
| O eixo | Onde e quando o HTML nasce — build · servidor · navegador |
| CSR | O navegador monta — melhor interatividade, piores primeira carga e SEO |
| SSR | O servidor monta a cada requisição — fresco, forte em SEO, TTFB maior |
| SSG | Pré-construído no build, servido por CDN — o mais rápido e barato, velho até o próximo build |
| O reenquadramento | Mesma API, três momentos de chamada — é por rota, não por app |
Os mesmos dados, três momentos de chamada
// JavaScript — the SAME API call, consumed three ways.
// Rendering is a FRONTEND choice; the data is a BACKEND concern.
async function getPosts() {
const q = new Parse.Query('Post').equalTo('published', true).limit(20);
return q.find(); // one backend endpoint — the ONLY thing that changes is WHEN
}
// SSG — called at BUILD time; data baked into static HTML, served from a CDN.
// SSR — called PER REQUEST on the server; fresh HTML sent to the browser.
// CSR — called FROM THE BROWSER after load; the client builds the DOM.
// You don't change the backend to switch rendering — only when/where you fetch. // Flutter / Dart — Back4app Flutter SDK
// Whatever the rendering strategy, the data comes from one backend API.
Future<List<ParseObject>> getPosts() async {
final q = QueryBuilder<ParseObject>(ParseObject('Post'))
..whereEqualTo('published', true)
..setLimit(20);
return (await q.query()).results?.cast<ParseObject>() ?? [];
}
// SSG fetches at build, SSR fetches per request, CSR fetches in the client —
// the endpoint is identical; only the timing and location differ. // Swift — Back4app Swift SDK
// Whatever the rendering strategy, the data comes from one backend API.
func getPosts() async throws -> [Post] {
try await Post.query("published" == true).limit(20).find()
}
// SSG fetches at build, SSR fetches per request, CSR fetches in the client —
// the endpoint is identical; only the timing and location differ. // Kotlin — Back4app Android SDK
// Whatever the rendering strategy, the data comes from one backend API.
fun getPosts(): List<ParseObject> {
val q = ParseQuery.getQuery<ParseObject>("Post")
q.whereEqualTo("published", true)
q.limit = 20
return q.find()
}
// SSG fetches at build, SSR fetches per request, CSR fetches in the client —
// the endpoint is identical; only the timing and location differ. Um getPosts(), um endpoint de backend. O SSG o chama no build e assa o resultado em HTML estático; o SSR o chama no servidor, a cada requisição, e envia HTML fresco; o CSR o chama do navegador, depois do carregamento. Você nunca muda o backend para mudar a renderização — só o momento e o lugar do fetch. É esse fato que transforma uma comparação confusa de três vias numa única decisão.
SSR vs. CSR vs. SSG, lado a lado
| CSR | SSR | SSG | |
|---|---|---|---|
| HTML gerado | No navegador | No servidor, por requisição | No build |
| TTFB | Rápido | Maior (renderiza antes) | O mais rápido, consistente |
| Primeira pintura (FCP) | Lenta | Rápida | Rápida |
| Interativo (TTI) | Lento | Após a hidratação | Após a hidratação |
| SEO | O mais arriscado | Forte | Forte |
| Frescor dos dados | Ao vivo | Ao vivo | Do último build |
| Custo | Servidor barato | Servidor por requisição | O mais barato (estático) |
| Melhor para | Dashboards, apps | Personalizado, fresco | Conteúdo, docs, marketing |
As métricas, com honestidade
Os trade-offs que nenhuma comparação enuncia com clareza. O SSG vence o time-to-first-byte de lavada e com consistência — a CDN devolve um arquivo pré-construído. O SSR aumenta o TTFB (o servidor precisa renderizar antes de responder), mas ainda bate o CSR na primeira pintura, e entrega dados frescos. O CSR tem TTFB rápido (o shell é minúsculo), mas primeira pintura e time-to-interactive lentos, porque nada aparece até o bundle rodar. E o ponto que todo mundo passa por cima: SSR e SSG não consertam o TTI. Ambos enviam HTML que parece pronto, e então a hidratação — baixar, interpretar e executar o JavaScript que anexa a interatividade — roda de qualquer jeito. É a lacuna do “parece pronto mas não clica”, e é por isso que a conta de JS enviado é o verdadeiro imposto da interatividade — motivando islands, hidratação parcial e server components, que enviam menos dele.
O espectro moderno: ISR, streaming, RSC
O trio é uma simplificação didática; produção é um espectro. O ISR (incremental static regeneration) serve páginas estáticas, mas regenera páginas individuais num intervalo de revalidação ou sob demanda — velocidade de SSG com frescor periódico, ao preço de alguma desatualização ocasional. O SSR com streaming envia o HTML em pedaços conforme é gerado, então o shell pinta em dezenas de milissegundos enquanto o conteúdo lento chega atrás. Os server components rodam só no servidor, enviam zero JavaScript para as partes não interativas e podem ler dados diretamente — a resposta mais nova ao custo da hidratação. Nenhum deles muda o contrato com o backend; são controle mais fino sobre quando o HTML se forma e quanto JS vem atrás dele — o mesmo eixo em torno do qual este verbete inteiro gira.
É por rota, não por app
O upgrade mental que dissolve a maioria dos debates de “qual delas?”: você não escolhe uma estratégia para o site inteiro. Um único app rotineiramente as mistura — home de marketing gerada estaticamente, catálogo de produtos regenerado via ISR, dashboard personalizado renderizado no servidor e widgets interativos renderizados no cliente — cada rota escolhendo pelas próprias necessidades. A pergunta nunca é “SSR, CSR ou SSG para o meu app?”, e sim “qual para esta página?”, e a resposta segue os dados da página: igual para todos e estável → estático; personalizado ou fresco → servidor; atrás de login e altamente interativo → cliente.
Qual estratégia para cada página? Matriz de decisão
| Tipo de página | Renderização |
|---|---|
| Marketing, landing, blog, docs | SSG |
| Catálogo de produtos, notícias, feeds | ISR (estático + atualização periódica) |
| Personalizado, atrás de login, carrinho, busca | SSR (ou streaming) |
| Dashboards, ferramentas internas | CSR |
| Tempo real, altamente interativo | CSR + dados ao vivo |
| Conteúdo crítico para SEO | CSR não — renderize no servidor ou pré-construa |
Casos de uso comuns
- Sites de conteúdo — SSG mais uma CDN para páginas instantâneas e amigáveis a crawlers (o padrão JAMstack).
- E-commerce — catálogo em ISR, carrinho e checkout em SSR, filtros interativos em CSR — três estratégias, uma loja.
- Dashboards SaaS — CSR atrás do login, onde SEO não importa e interatividade importa.
- Notícias e publishing — SSR ou ISR para frescor com SEO.
- PWAs — um shell renderizado mais interatividade no cliente e cache offline.
Limitações e trade-offs
- O risco de SEO do CSR é real, mas exagerado. Crawlers renderizam JavaScript com um orçamento; CSR é tranquilo fora do caminho indexável e uma aposta dentro dele — nuance, não absolutismo.
- SSR custa computação de servidor. Renderizar cada requisição tem um preço em TTFB e infraestrutura que um arquivo estático servido por CDN não tem.
- A defasagem de frescor do SSG. Dados de build ficam velhos até o próximo build; sites grandes ou que mudam rápido precisam de ISR ou de builds longos.
- Hidratação é o imposto escondido. HTML renderizado no servidor ainda envia JS para ficar interativo; primeira pintura rápida, primeiro clique nem tanto.
- Misturar adiciona carga cognitiva. Renderização por rota é poderosa e significa raciocinar sobre vários timings de fetch num mesmo app — a flexibilidade tem custo de complexidade.
Renderização no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. Ele é a constante por baixo da escolha de renderização: as APIs REST e GraphQL alimentam o SSG no build, o SSR por requisição no servidor e o CSR do navegador — o endpoint idêntico das abas de código, consumido em três momentos diferentes — de modo que trocar a estratégia de uma rota nunca toca o backend. O reenquadramento que abre este artigo vira conveniência de trabalho: como renderização é uma decisão de frontend e os dados moram atrás de uma API estável com autenticação e permissões próprias, um time pode pré-construir o blog, renderizar o dashboard no servidor e renderizar o shell do app no cliente contra o mesmo backend Back4app — escolhendo por página, sem mudar nada por baixo.
Perguntas frequentes
O que é CSR (renderização no cliente)?
O servidor envia um HTML quase vazio mais um bundle de JavaScript; o navegador baixa, interpreta e executa o JS, busca os dados numa API e monta a página. O usuário vê uma tela em branco ou um spinner até o JavaScript rodar — a melhor interatividade, o pior carregamento inicial e SEO.
O que é SSR (renderização no servidor)?
O servidor gera o HTML completo a cada requisição — executando código e buscando dados — e envia um documento pronto para pintar, que depois é hidratado para ganhar interatividade. SEO forte e primeira pintura rápida com dados sempre frescos, ao custo de computação no servidor e um time-to-first-byte maior.
O que é SSG (geração de site estático)?
O HTML de cada página é pré-construído no build em arquivos estáticos e servido de uma CDN, sem trabalho de servidor por requisição. A opção mais rápida, barata e amigável a SEO — mas os dados só são tão frescos quanto o último build, e ela encaixa mal em rotas desconhecidas ou altamente dinâmicas.
Qual a diferença entre SSR, CSR e SSG?
Onde e quando o HTML é gerado: no build (SSG), no servidor a cada requisição (SSR) ou no navegador em runtime (CSR). Todo o resto — SEO, performance, frescor dos dados, custo — decorre dessa única escolha.
Qual estratégia de renderização é melhor para SEO?
SSG e SSR, porque os crawlers recebem HTML completo. CSR é a mais arriscada, já que os bots precisam executar JavaScript para ver o conteúdo, o que atrasa ou pode custar a indexação. A nuance: crawlers modernos renderizam JavaScript, mas com um orçamento — CSR serve para superfícies não indexáveis e é uma aposta para conteúdo que precisa ranquear.
O que é hidratação (hydration)?
Anexar JavaScript — event listeners e estado — a um HTML já renderizado no servidor, para que uma página de aparência estática se torne interativa. A pegadinha: o JS ainda precisa baixar, interpretar e executar, então a página pode parecer pronta e continuar sem responder a cliques, atrasando o time-to-interactive mesmo quando a primeira pintura foi rápida.
Qual a diferença entre SSR e SSG?
SSG para conteúdo igual para todo mundo e que muda raramente — docs, blogs, marketing. SSR para páginas personalizadas, atrás de autenticação ou que mudam com frequência suficiente para dados de build ficarem velhos. O conselho padrão: prefira SSG e recorra a SSR só onde o frescor por requisição é obrigatório.
Dá para misturar estratégias no mesmo app?
Sim — a prática moderna é por rota, até por componente: páginas de marketing estáticas, catálogo regenerado, dashboards renderizados no servidor e widgets renderizados no cliente convivem num mesmo app. Renderização é uma decisão que você toma por página, não uma vez para o site inteiro.