SSR vs. CSR vs. SSG è un confronto tra strategie di rendering in base a dove e quando viene generato l’HTML: in fase di build, sul server o nel browser. Quell’unico asse – dove e quando – determina SEO, prestazioni, freschezza dei dati e costo; tutto il resto ne discende. E la precisazione da sviluppatore backend che le guide frontend seppelliscono: il rendering è una questione di frontend; i dati sono una questione di backend. Tutte e tre le strategie chiamano la stessa API; differiscono solo nel momento in cui la chiamano.
Punti chiave
| Domanda | Risposta |
|---|---|
| L’asse | Dove e quando viene prodotto l’HTML – build · server · browser |
| CSR | Lo costruisce il browser – migliore interattività, peggiori primo caricamento e SEO |
| SSR | Lo costruisce il server a ogni richiesta – fresco, solido in SEO, TTFB più alto |
| SSG | Precompilato in fase di build, servito da un CDN – il più veloce, il più economico, non aggiornato fino alla build successiva |
| La rilettura | Stessa API, tre momenti di chiamata – per rotta, non per app |
Stessi dati, tre momenti di chiamata
// 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. Un solo getPosts(), un solo endpoint backend. L’SSG lo chiama in fase di build e fissa il risultato in HTML statico; l’SSR lo chiama a ogni richiesta, sul server, e invia HTML fresco; il CSR lo chiama dal browser dopo il caricamento. Il backend non cambia mai per cambiare rendering – cambiano solo il momento e il luogo in cui si recuperano i dati. È questo il fatto che trasforma un confronto a tre vie confuso in un’unica decisione.
SSR vs. CSR vs. SSG, fianco a fianco
| CSR | SSR | SSG | |
|---|---|---|---|
| HTML generato | Nel browser | Sul server, per richiesta | In fase di build |
| TTFB | Veloce | Più alto (prima renderizza) | Il più veloce, costante |
| Primo rendering (FCP) | Lento | Veloce | Veloce |
| Interattività (TTI) | Lenta | Dopo l’hydration | Dopo l’hydration |
| SEO | La più rischiosa | Solida | Solida |
| Freschezza dei dati | Live | Live | Quella dell’ultima build |
| Costo | Server leggero | Server per richiesta | Il più economico (statico) |
| Ideale per | Dashboard, app | Personalizzato, fresco | Contenuti, documentazione, marketing |
Le metriche, onestamente
I trade-off che nessun confronto dichiara in modo pulito. L’SSG vince il time-to-first-byte nettamente e con costanza – un CDN restituisce un file precompilato. L’SSR alza il TTFB (il server deve renderizzare prima di poter rispondere) ma batte comunque il CSR sul primo rendering, e consegna dati freschi. Il CSR ha un TTFB veloce (la shell è minuscola) ma un primo rendering e un time-to-interactive lenti, perché nulla è visibile finché il bundle non viene eseguito. E quello su cui tutti sorvolano: SSR e SSG non risolvono il TTI. Entrambi inviano un HTML che sembra pronto, poi l’hydration – scaricare, analizzare ed eseguire il JavaScript per collegare l’interattività – gira comunque. È il divario “sembra pronto ma non è cliccabile”, ed è il motivo per cui il conto del JS spedito è la vera tassa sull’interattività, che motiva island, hydration parziale e server component che ne spediscono meno.
Lo spettro del 2026: ISR, streaming, RSC
Il trio è una semplificazione didattica; la produzione è uno spettro. L’ISR (incremental static regeneration) serve pagine statiche ma le rigenera a intervalli o su richiesta – la velocità dell’SSG con freschezza periodica, al prezzo di contenuti ogni tanto non aggiornati. Lo streaming SSR invia l’HTML a blocchi man mano che viene generato, così la shell si disegna in poche decine di millisecondi mentre il contenuto lento arriva dietro. I server component girano solo sul server, spediscono zero JavaScript per le parti non interattive e possono leggere i dati direttamente – la risposta più recente al costo dell’hydration. Nessuno di questi cambia il contratto con il backend; sono un controllo più fine su quando l’HTML prende forma e quanto JS lo segue, cioè lo stesso asse attorno a cui ruota tutto questo articolo.
Per rotta, non per app
Il salto mentale che dissolve la maggior parte dei dibattiti su “quale scegliere?”: non si sceglie una strategia per l’intero sito. Una singola app le mescola abitualmente – una home page di marketing generata staticamente, un catalogo prodotti rigenerato con ISR, una dashboard personalizzata renderizzata sul server e widget interattivi renderizzati sul client – con ogni rotta che sceglie in base alle proprie esigenze. La domanda non è mai “SSR, CSR o SSG per la mia app?” ma “quale per questa pagina?”, e la risposta segue i dati della pagina: uguali per tutti e stabili → statico; personalizzati o freschi → server; dietro un login e molto interattivi → client.
Quale strategia per ogni pagina? Matrice decisionale
| Tipo di pagina | Rendering |
|---|---|
| Marketing, landing page, blog, documentazione | SSG |
| Catalogo prodotti, notizie, feed | ISR (statico + aggiornamento periodico) |
| Personalizzata, protetta da autenticazione, carrello, ricerca | SSR (o streaming) |
| Dashboard, strumenti interni | CSR |
| Tempo reale, molto interattiva | CSR + dati live |
| Contenuti critici per la SEO | Non CSR – rendering lato server o precompilazione |
Casi d’uso comuni
- Siti di contenuti – SSG più un CDN per pagine istantanee e leggibili dai crawler (il pattern JAMstack).
- E-commerce – pagine di catalogo in ISR, carrello e pagamento in SSR, filtri interattivi in CSR – tre strategie, un solo negozio.
- Dashboard SaaS – CSR dietro un login, dove la SEO non conta e l’interattività sì.
- Notizie ed editoria – SSR o ISR per la freschezza insieme alla SEO.
- PWA – una shell renderizzata più interattività lato client e cache offline.
Limiti e trade-off
- Il rischio SEO del CSR è reale ma esagerato. I crawler eseguono il JavaScript con un budget; il CSR va bene fuori dal percorso indicizzabile ed è una scommessa su di esso – sfumatura, non assolutismo.
- L’SSR costa calcolo sul server. Renderizzare ogni richiesta ha un prezzo in TTFB e infrastruttura che un file statico servito da un CDN non ha.
- Il ritardo di freschezza dell’SSG. I dati della build restano non aggiornati fino alla build successiva; i siti grandi o che cambiano in fretta hanno bisogno di ISR o di build lunghe.
- L’hydration è la tassa nascosta. L’HTML renderizzato sul server spedisce comunque JS per diventare interattivo; primo rendering veloce, primo clic non necessariamente.
- Mescolare aggiunge carico cognitivo. Il rendering per rotta è potente e comporta ragionare su più momenti di recupero dei dati in un’unica app – la flessibilità ha un costo in complessità.
Il rendering su Back4app
Back4app è una piattaforma open-source di Backend as a Service (BaaS) che combina database gestito, API REST e GraphQL generate automaticamente, autenticazione, archiviazione di file e funzioni serverless con Cloud Code. È la costante sotto la scelta di rendering: le API REST e GraphQL alimentano l’SSG in fase di build, l’SSR a ogni richiesta sul server e il CSR dal browser – lo stesso identico endpoint mostrato dalle schede di codice, consumato in tre momenti diversi – così cambiare la strategia di una rotta non tocca mai il backend. La rilettura con cui si apre questo articolo diventa una comodità concreta: poiché il rendering è una decisione frontend e i dati vivono dietro un’unica API stabile con la propria autenticazione e i propri permessi, un team può precompilare il blog, renderizzare la dashboard sul server e renderizzare la shell dell’app sul client sullo stesso backend Back4app – scegliendo pagina per pagina, senza cambiare nulla sotto.
Domande frequenti
Che cos'è il CSR (rendering lato client)?
Il server invia una shell HTML quasi vuota più un bundle JavaScript; il browser scarica, analizza ed esegue il JS, recupera i dati da un'API e costruisce la pagina. L'utente vede uno schermo bianco o uno spinner finché il JavaScript non viene eseguito – la migliore interattività, ma il peggior caricamento iniziale e la peggiore SEO.
Che cos'è l'SSR (rendering lato server)?
Il server genera l'HTML completo a ogni richiesta – eseguendo codice e recuperando i dati – e invia un documento pronto da disegnare, che viene poi idratato per diventare interattivo. SEO solida e primo rendering veloce con dati sempre freschi, al costo di calcolo sul server e di un time-to-first-byte più alto.
Che cos'è l'SSG (generazione statica)?
L'HTML di ogni pagina viene precompilato in fase di build in file statici serviti da un CDN, senza alcun lavoro del server per richiesta. L'opzione più veloce, economica e favorevole alla SEO – ma i dati sono freschi solo quanto l'ultima build, e si adatta male alle rotte sconosciute o molto dinamiche.
Qual è la differenza tra SSR, CSR e SSG?
Dove e quando viene generato l'HTML: in fase di build (SSG), sul server a ogni richiesta (SSR) o nel browser a runtime (CSR). Tutto il resto – SEO, prestazioni, freschezza dei dati, costo – discende da questa sola scelta.
Quale strategia di rendering è la migliore per la SEO?
SSG e SSR, perché i crawler ricevono un HTML completo. Il CSR è il più rischioso, perché i bot devono eseguire il JavaScript per vedere il contenuto, il che ritarda l'indicizzazione o può comprometterla. La sfumatura: i crawler moderni eseguono il JavaScript, ma con un budget – quindi il CSR va bene per le superfici non indicizzabili ed è una scommessa per i contenuti che devono posizionarsi.
Che cos'è l'hydration?
Collegare il JavaScript – listener di eventi e stato – a un HTML già renderizzato dal server, così che una pagina dall'aspetto statico diventi interattiva. L'insidia: il JS deve comunque essere scaricato, analizzato ed eseguito, quindi una pagina può sembrare pronta restando non cliccabile, ritardando il time-to-interactive anche quando il primo rendering è stato veloce.
Quando conviene usare l'SSR invece dell'SSG?
L'SSG per contenuti uguali per tutti e che cambiano di rado – documentazione, blog, marketing. L'SSR per le pagine personalizzate, protette da autenticazione o che cambiano abbastanza spesso da rendere obsoleti i dati della build. Il consiglio predefinito: preferire l'SSG e ricorrere all'SSR solo dove serve freschezza a ogni richiesta.
Si usa una sola strategia per app?
No – la pratica moderna è per rotta, perfino per componente: pagine di marketing statiche, pagine di catalogo rigenerate, dashboard renderizzate sul server e widget renderizzati sul client possono convivere in un'unica app. Il rendering è una decisione che si prende pagina per pagina, non una volta per l'intero sito.