Next.js 16 vs Remix
Next.js 16 (Turbopack als Standard, Partial Prerendering) vs. Remix (Shopify, Web-Standards) — Vergleich von React-Meta-Frameworks 2026.
Die serverseitig vorgerenderte React-Schicht mit Zero-JS-Standard
Die klassische, ausgereifte React-Nutzungsform, die im Browser gerendert wird
Bei inhaltslastigen, SEO-kritischen Oberflächen liefert RSC einen messbaren Gewinn: Im Beispiel von react.dev gelangt eine 75-KB-gzip-Bibliothek überhaupt nicht zum Client. Bei stark interaktiven internen Panels (Dashboard, Admin) bietet Client-First sowohl mehr Einfachheit als auch weniger Fehlerfläche. Die kritische Warnung ist real: Wird ein komplettes Objekt als Prop von Server zu Client übergeben, landen alle Felder des Objekts im Flight-Payload – wird die Grenze falsch gezogen, verpufft der Gewinn stillschweigend. Treffen Sie die Entscheidung anhand von Messungen, nicht nach Trend.
| Kategorie | React Server Components | Client-side React (SPA) |
|---|---|---|
| Performance | 8/10 | 6/10 |
| Erlernbarkeit | 4/10 | 8/10 |
| Ökosystem | 7/10 | 9/10 |
| Community | 7/10 | 9/10 |
| Arbeitsmarkt | 7/10 | 8/10 |
| Zukunftssicherheit | 9/10 | 7/10 |
// Next.js App Router – Server Component (Standard)
// app/posts/[slug]/page.tsx
import { db } from '@/lib/db';
import LikeButton from './like-button'; // Client Component (in separater Datei 'use client')
interface PageProps {
params: Promise<{ slug: string }>;
}
export default async function PostPage({ params }: PageProps) {
const { slug } = await params;
// Direktes await auf Serverseite — kein Client-Server-Waterfall,
// schwere Bibliotheken wie marked/sanitize-html gelangen nie in das Client-Bundle
const post = await db.post.findUnique({ where: { slug } });
if (!post) return <div>Nicht gefunden</div>;
return (
<article>
<h1>{post.title}</h1>
{/* Nur serialisierbare Props werden an die Client Component übergeben */}
<div dangerouslySetInnerHTML={{ __html: post.renderedHtml }} />
<LikeButton postId={post.id} initialCount={post.likeCount} />
</article>
);
}
// app/posts/[slug]/like-button.tsx
'use client';
import { useState, useTransition } from 'react';
export default function LikeButton({ postId, initialCount }: { postId: string; initialCount: number }) {
const [count, setCount] = useState(initialCount);
const [isPending, startTransition] = useTransition();
return (
<button
disabled={isPending}
onClick={() => startTransition(async () => {
setCount((c) => c + 1);
await fetch(`/api/posts/${postId}/like`, { method: 'POST' });
})}
>
Gefällt mir ({count})
</button>
);
}// Vite + React – Client-seitige SPA
// src/pages/PostPage.tsx
import { useEffect, useState } from 'react';
import { useParams } from 'react-router';
interface Post {
id: string;
title: string;
renderedHtml: string;
likeCount: number;
}
export default function PostPage() {
const { slug } = useParams();
const [post, setPost] = useState<Post | null>(null);
const [isLiking, setIsLiking] = useState(false);
useEffect(() => {
// Das gesamte Data-Fetching läuft im Client — hier beginnt das Waterfall-Risiko
let cancelled = false;
fetch(`/api/posts/${slug}`)
.then((res) => res.json())
.then((data) => { if (!cancelled) setPost(data); });
return () => { cancelled = true; };
}, [slug]);
if (!post) return <div>Lädt...</div>; // Ohne laufendes JS wird dieser Bildschirm nie angezeigt
async function handleLike() {
setIsLiking(true);
setPost((p) => (p ? { ...p, likeCount: p.likeCount + 1 } : p));
await fetch(`/api/posts/${post!.id}/like`, { method: 'POST' });
setIsLiking(false);
}
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.renderedHtml }} />
<button disabled={isLiking} onClick={handleLike}>
Gefällt mir ({post.likeCount})
</button>
</article>
);
}
// vite.config.ts — Code-Splitting wird an Rollup delegiert
export default {
build: {
rollupOptions: {
output: { manualChunks: { vendor: ['react', 'react-dom', 'react-router'] } },
},
},
};Bei inhaltslastigen, SEO-kritischen Oberflächen liefert RSC einen messbaren Gewinn: Im Beispiel von react.dev gelangt eine 75-KB-gzip-Bibliothek überhaupt nicht zum Client. Bei stark interaktiven internen Panels (Dashboard, Admin) bietet Client-First sowohl mehr Einfachheit als auch weniger Fehlerfläche. Die kritische Warnung ist real: Wird ein komplettes Objekt als Prop von Server zu Client übergeben, landen alle Felder des Objekts im Flight-Payload – wird die Grenze falsch gezogen, verpufft der Gewinn stillschweigend. Treffen Sie die Entscheidung anhand von Messungen, nicht nach Trend.
Kostenlose Beratung erhaltenBei inhaltslastigen, SEO-kritischen Oberflächen, bei denen das initiale Laden (LCP/TTI) wichtig ist (Blog, Produktseite, Vergleichsseite), liefert RSC einen messbaren Gewinn — serverseitiges Data-Fetching und weniger Client-JS. Laut eigenen Daten von Next.js 16.3 können durch den Umstieg auf native Node.js-Streams beim serverseitigen Rendering unter Last 22 % mehr Requests verarbeitet werden. Bei stark interaktiven internen Panels (Dashboard, Admin) bietet Client-First in der Regel eine einfachere Entwicklungserfahrung.