
von Zelkulon12. März 20251 min Lesezeit
Next.js baut auf React auf – aber die Unterschiede sind gewaltig. Server Components, App Router, Streaming: Was bedeutet das konkret für die Architektur?
Was leistet was?
React (Bibliothek): Next.js (Framework): ──────────────────── ──────────────────────────────── ✓ UI-Komponenten ✓ Alles von React ✓ State Management ✓ File-based Routing ✓ Hooks ✓ Server Components (RSC) ✗ Routing (selbst wählen) ✓ Server-side Rendering (SSR) ✗ Server-Rendering ✓ Static Site Generation (SSG) ✗ Image-Optimierung ✓ API Routes + Image-Optimierung
Die Rendering-Strategien im Vergleich
Strategie Wann gerendert? Wann neu? Use Case ────────────────────────────────────────────────────────────────── SSG (Static) Build-Zeit Neuer Build Blog, Docs ISR Build + Interval Nach X Sekunden Produktliste SSR Jeder Request Jeder Request Dashboard RSC (Server) Jeder Request Per Bedarf Standard Client Comp. Browser Per Bedarf Interaktiv
Server Component vs. Client Component
// Server Component (Default im Next.js App Router)
// KEIN "use client" → läuft auf dem Server
async function BlogPage() {
// Direkter DB/API-Zugriff auf dem Server
const posts = await fetch('https://api.example.com/posts', {
next: { revalidate: 3600 } // ISR: stündlich aktualisieren
}).then(r => r.json());
return (
<div>
{posts.map((post: Post) => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</div>
);
}
// Client Component – nur wo nötig
"use client";
export function SearchBar() {
const [query, setQuery] = useState('');
return (
<input
value={query}
onChange={e => setQuery(e.target.value)}
placeholder="Suchen..."
/>
);
}Datenabruf: useEffect vs. Server Component
// React (useEffect-Pattern) – im Browser
function ProductList() {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('/api/products')
.then(r => r.json())
.then(data => { setProducts(data); setLoading(false); });
}, []);
if (loading) return <Spinner />;
return <ProductGrid products={products} />;
}
// Next.js (Server Component) – auf dem Server
async function ProductList() {
const products = await getProducts(); // Kein Loading-State nötig!
return <ProductGrid products={products} />;
}
// Suspense für Streaming
export default function Page() {
return (
<Suspense fallback={<ProductSkeleton />}>
<ProductList /> {/* Skelett bis Daten da */}
</Suspense>
);
}Wann React allein, wann Next.js?
Wähle reines React (+ Vite) wenn: ────────────────────────────────── ✓ Single-Page-App (SPA) hinter Login ✓ SEO ist nicht wichtig ✓ Maximale Freiheit gewünscht Beispiele: Admin-Dashboard, interne Tools Wähle Next.js wenn: ──────────────────── ✓ SEO wichtig (Landing Pages, Blog, E-Commerce) ✓ Initiale Ladezeit soll minimal sein ✓ Full-Stack mit API Routes gewünscht ✓ Große Anwendung mit vielen Routen Beispiele: Unternehmenswebsite, SaaS, E-Commerce
Performance-Vergleich
Typische Werte in der Praxis:
- First Contentful Paint: React CSR ~2,5s | Next.js SSR ~0,5s | SSG ~0,2s
- Time to Interactive: React CSR ~3,5s | Next.js SSR ~1,5s | SSG ~0,5s
- Bundle-Größe: React CSR 300-500 KB | Next.js RSC 80-150 KB | SSG 30-80 KB
- SEO-Score: React CSR mittel | Next.js SSR sehr gut | SSG exzellent