Single Page Application
Rendering vollständig im Browser – der Server liefert nur ein leeres HTML-Gerüst + JS-Bundle.
index.html mit einem JavaScript-Bundle. Der Browser lädt dieses Bundle, und Vue/React baut das komplette HTML im Browser auf. Alle Daten werden zur Laufzeit per API-Call vom Browser geholt. Der Server ist passiv – er versteht die App nicht, er liefert nur Dateien aus.
// Kein HTML vom Server – der Browser baut alles auf. Kein Hydration-Schritt nötig.
Datenbasis
Vollständig dynamisch
Alle Daten werden zur Laufzeit per API-Call geholt. Die App kennt beim Build keine Inhalte – alles kommt vom Backend während der Nutzer die Seite besucht.
Node-Prozess
Nicht erforderlich
Das fertige dist/-Verzeichnis sind reine statische Dateien. Apache, Nginx oder ein CDN reichen vollständig aus. Node nur nötig wenn eine eigene API gebaut wird – das ist aber eine separate Entscheidung.
Hydration
Nicht vorhanden
Es gibt kein server-gerendertes HTML das "aktiviert" werden muss. Das JS übernimmt von Anfang an die volle Kontrolle und baut den DOM komplett auf.
Vorteile
- Reiches, reaktives UI/UX-Erlebnis
- Kein Server zur Laufzeit nötig
- Einfachstes Hosting – jeder Webserver
- Schnelle Navigation nach Initial-Load
- Backend-Technologie frei wählbar
- Ideal für Auth-geschützte Bereiche
Nachteile
- Schlechtes SEO (leeres HTML für Crawler)
- Langsames Initial-Load (JS muss erst laden)
- Kein serverseitiger State möglich
- Daten erst sichtbar nach JS-Ausführung
- Schlechte Performance auf schwachen Geräten
SEO
Schlecht
Initial-Speed (FCP)
Langsam
Interaktivität
Exzellent
Hosting-Kosten
Minimal
Datenaktualität
Immer aktuell
# Vue 3 + Vite (Standard SPA) npm create vue@latest my-app cd my-app && npm install npm run build # → dist/ → auf beliebigen Webserver hochladen # React + Vite npm create vite@latest my-app -- --template react
Server-Side Rendering
Rendering auf dem Server bei jedem eingehenden Request – fertiges HTML sofort an den Browser.
// Jeder Request trifft den Node-Server. Kein Caching = immer frische Daten.
Datenbasis
Vollständig dynamisch
Der Server liest DB oder API bei jedem Request. Nutzerspezifische, zeitkritische oder personalisierte Inhalte sind problemlos möglich. Kein Build nötig nach Datenänderungen.
Node-Prozess
Zwingend erforderlich
Ein dauerhaft laufender Node-Prozess (z.B. via PM2) ist nicht optional. Der Server muss JavaScript verstehen um Vue/React-Komponenten rendern zu können. Apache/Nginx allein reichen nicht.
Hydration
Ja – nach HTML-Empfang
Browser empfängt fertiges HTML, lädt danach das JS-Bundle nach. Vue/React "erkennt" das HTML wieder und aktiviert Event-Handler und Reaktivität. Seite ist kurz darstellbar aber nicht interaktiv (TTI > FCP).
Vorteile
- Sehr gutes SEO – vollständiges HTML für Crawler
- Schnelles FCP (First Contentful Paint)
- Immer aktuelle Daten
- Nutzerspezifischer Content möglich
- Keine Sichtbarkeit von API-Keys im Client
Nachteile
- Node-Server dauerhaft erforderlich
- Höhere Serverkosten als SSG/SPA
- Skalierung komplexer
- Latenz pro Request (DB-Query-Zeit)
- Hydration-Mismatch kann zu Bugs führen
SEO
Sehr gut
Initial-Speed (FCP)
Mittel
Datenaktualität
Immer aktuell
Hosting-Kosten
Hoch
Nutzer-spezifisch
Ja – pro Request
// nuxt.config.ts export default defineNuxtConfig({ ssr: true, // Standard in Nuxt 3 routeRules: { '/dashboard/**': { ssr: false }, // SPA für Auth-Bereich '/api/**': { cors: true } } }) // Server starten via PM2 pm2 start "node .output/server/index.mjs" --name my-app
Klassisches PHP (Server-Side Rendering ohne Hydration)
Der Ursprung von SSR: HTML wird bei jedem Request direkt auf dem Server erzeugt – ganz ohne JS-Framework, Build-Schritt oder Hydration.
// Kein Hydration-Schritt, kein JS-Bundle nötig – das HTML ist von Anfang an das fertige, interaktive Ergebnis.
Datenbasis
Vollständig dynamisch
Wie SSR: die DB wird bei jedem Request live abgefragt. Personalisierte, nutzerspezifische oder zeitkritische Inhalte sind der Standardfall, kein Build nötig nach Datenänderungen.
Node-Prozess
Nicht erforderlich
Statt eines Node-Prozesses übernimmt PHP-FPM (oder mod_php) die Ausführung. Läuft auf jedem klassischen LAMP-/LEMP-Stack – ideal für Shared Hosting und Plesk-Setups ohne Node/PM2.
Hydration
Existiert nicht
Es gibt keinen Client-seitigen Zustand, den ein Framework "übernehmen" müsste. Interaktivität entsteht klassisch über Formulare, Links und optional isoliertes Vanilla-JS/jQuery – kein Hydration-Mismatch möglich.
Vorteile
- Sehr gutes SEO – vollständiges HTML sofort
- Sofort interaktiv, kein Hydration-Delay
- Kein Node/PM2 nötig – klassisches Shared Hosting reicht
- Riesiges Ökosystem (WordPress, Laravel, Symfony, Shopware)
- Sehr niedrige Einstiegshürde, breite Hosting-Verfügbarkeit
- Nutzerspezifischer Content ohne Zusatzaufwand
Nachteile
- Kein reaktives UI ohne zusätzliches JS
- Full-Page-Reload bei jeder Navigation
- Latenz pro Request (PHP-Ausführung + DB-Query)
- Kein Component-Sharing zwischen Server/Client wie bei SSR-Frameworks
- Skalierung meist vertikal (mehr PHP-Worker) statt CDN-Edge
SEO
Sehr gut
Initial-Speed (FCP)
Schnell (kein JS-Bundle nötig)
Datenaktualität
Immer aktuell
Hosting-Kosten
Niedrig (Standard-Webhosting)
Nutzer-spezifisch
Ja – pro Request
// index.php – Daten holen und direkt als HTML ausgeben <?php $stmt = $pdo->query('SELECT title, body FROM posts ORDER BY id DESC'); ?> <ul> <?php foreach ($stmt as $post): ?> <li><?= htmlspecialchars($post['title']) ?></li> <?php endforeach; ?> </ul> # Nginx – Anbindung an PHP-FPM (kein Node nötig) location ~ \.php$ { fastcgi_pass unix:/run/php/php8.5-fpm.sock; }
Static Site Generation
Alle Seiten werden einmalig beim Build als statische HTML-Dateien erzeugt. Kein Laufzeit-Server.
// Kein DB-Zugriff zur Laufzeit. Kein Node-Prozess. Maximale Performance.
Datenbasis
Statisch (Stand: letzter Build)
Daten werden einmalig beim Build aus CMS, DB oder API gezogen. Zur Laufzeit gibt es keinen DB-Zugriff. Ändert sich der Content, muss neu gebaut werden – manuell oder via CI/CD-Webhook.
Node-Prozess
Nur während des Builds
Node läuft ausschließlich beim Build. Das Ergebnis sind statische Dateien die auf Apache, Nginx, Plesk, S3 oder einem CDN liegen. Kein PM2, kein dauerhafter Prozess auf dem Server nötig.
Deployment
Einfachstes Deployment
Build lokal oder in CI/CD (GitHub Actions, etc.) erzeugen, dist/-Ordner auf den Webserver laden. Deployment ist identisch zu einer statischen HTML-Seite – für Plesk-Setups ideal.
Vorteile
- Maximale Performance – vorgerendertes HTML
- CDN-auslieferbar, kein Laufzeit-Server
- Bestes SEO – vollständiges HTML sofort
- Sehr günstig zu hosten
- Einfachstes Deployment
- Kein Single Point of Failure (Server)
Nachteile
- Kein dynamischer / nutzerspezifischer Content
- Rebuild nötig bei jeder Inhaltsänderung
- Langsamer Build bei sehr vielen Seiten
- Kein Echtzeit-Content möglich
- Nicht geeignet für Auth-geschützte Inhalte
SEO
Exzellent
Initial-Speed (FCP)
Sehr schnell
Datenaktualität
Stand: letzter Build
Hosting-Kosten
Minimal
Nutzer-spezifisch
Nein
// nuxt.config.ts export default defineNuxtConfig({ ssr: true, routeRules: { '/**': { prerender: true } // alle Routen statisch } }) # Build ausführen npx nuxi generate # → .output/public/ = statische Dateien → auf Webserver hochladen # VitePress (Docs) npx vitepress build docs
Incremental Static Regeneration
Statisch wie SSG, aber mit automatischer Hintergrund-Regeneration nach einem TTL-Intervall.
// Node-Server läuft dauerhaft im Hintergrund für die Regeneration.
Datenbasis
Statisch mit TTL-Revalidierung
Daten werden beim Build und nach TTL-Ablauf aus DB/API neu gezogen. Kleine Verzögerung (je nach TTL) ist tolerierbar. Nicht geeignet für Echtzeit- oder nutzerspezifische Daten.
Node-Prozess
Zwingend erforderlich
Obwohl die Seiten gecacht wirken – ein Node-Server läuft im Hintergrund und übernimmt die Revalidierung. Kein laufender Prozess = kein ISR. Oft vergessen weil es sich wie SSG anfühlt.
On-Demand ISR
Auch möglich
Statt TTL-Intervall kann Regeneration auch on-demand via Webhook getriggert werden – z.B. wenn ein CMS-Eintrag gespeichert wird. Nuxt 3 und Next.js unterstützen beide Varianten.
Vorteile
- Statisch schnell – gecachtes HTML
- Automatische Aktualisierung ohne Rebuild
- CDN-kompatibel
- Gutes SEO
- Günstigere Serverkosten als reines SSR
- On-Demand Revalidierung via Webhook möglich
Nachteile
- Erster Besucher nach TTL sieht veraltete Version
- Node-Server trotzdem erforderlich
- Kein nutzerspezifischer Content
- Komplexere Logik als reines SSG
- TTL-Konfiguration erfordert Überlegung
SEO
Sehr gut
Initial-Speed (FCP)
Sehr schnell
Datenaktualität
Nach TTL-Ablauf
Hosting-Kosten
Niedrig–mittel
Nutzer-spezifisch
Nein
// nuxt.config.ts export default defineNuxtConfig({ routeRules: { '/products/**': { isr: 3600 }, // jede Stunde regenerieren '/news/**': { isr: 300 }, // alle 5 Minuten '/about': { prerender: true }, // reines SSG '/dashboard': { ssr: false } // SPA } }) // Next.js (Pages Router) export async function getStaticProps() { return { props: { data }, revalidate: 60 } // 60s TTL }
Vollständiger Vergleich
Alle vier Ansätze auf einen Blick.
| Kriterium | SPA | SSR | PHP (klassisch) | SSG | ISR |
|---|---|---|---|---|---|
| Rendering-Ort | Browser | Server (pro Request) | Server (pro Request) | Build-Zeit | Build + Hintergrund |
| Node-Prozess | ✓ Nein | ✕ Ja, zwingend | ✓ Nein (PHP-FPM) | ✓ Nur beim Build | ✕ Ja, zwingend |
| SEO | Schlecht | Sehr gut | Sehr gut | Exzellent | Sehr gut |
| Initial-Speed (FCP) | Langsam | Mittel | Schnell | Sehr schnell | Sehr schnell |
| Datenaktualität | Immer aktuell | Immer aktuell | Immer aktuell | Stand: letzter Build | Nach TTL-Ablauf |
| Nutzer-spezifisch | Ja | Ja | Ja | Nein | Nein |
| Hosting-Kosten | Minimal | Hoch | Niedrig | Minimal | Niedrig–mittel |
| Hydration | Nein | Ja – nach HTML-Empfang | Existiert nicht | Ja – optional | Ja – nach HTML-Empfang |
| Rebuild bei Änderung | Nein | Nein | Nein | Ja – zwingend | Nein – auto TTL |
| Datenbasis | API (runtime) | DB/API (runtime) | DB/API (runtime) | DB/API (build) | DB/API (build + TTL) |
| Hosting | Statisch / CDN | Node-Server | Apache/Nginx + PHP-FPM | Statisch / CDN | Node-Server + CDN |
| Frameworks | Vue + Vite, React + Vite | Nuxt 3, Next.js, SvelteKit | WordPress, Laravel, Symfony | VitePress, Nuxt generate, Astro | Next.js, Nuxt 3 (routeRules), Astro |
| Verhältnis zu PHP | Kein Äquivalent | Wie PHP, plus Hydration/JS-Framework | Referenzpunkt – der Ursprung von SSR | Kein Äquivalent | Kein Äquivalent |
Entscheidungshilfe
Welcher Ansatz für welches Projekt?
Welchen Modus brauche ich?
Dashboards, Admin-Tools, interne Apps, Web-Apps mit Authentifizierung
Vue + Vite
Personalisierter Feed, Live-Preise, Session-abhängige Daten
Nuxt 3 / Next.js
CMS, Shop, klassische Web-Anwendung, Standard-Webhosting ohne Node
Laravel / Symfony / WordPress
Blog, Doku, Portfolio, Landingpage, Firmenseite
VitePress / Nuxt generate
Produktkatalog, News, Preislisten – aktuell aber nicht Echtzeit
Nuxt routeRules / Next.js
Startseite SSG, Produktseiten ISR, Dashboard SPA, Checkout SSR
routeRules mixen