Ein fairer Vergleich ist wichtig: Weder ein klassisches CMS noch ein SSG ist pauschal besser. Entscheidend sind dein Team, der Workflow, die Änderungsfrequenz und die technischen Anforderungen.
| Kriterium |
Monolithisches CMS (z. B. WordPress / TYPO3) |
Modernes SSG-Setup (z. B. 11ty / Hugo + Cloudflare Pages) |
| Performance & Speed |
🟡 Mittelmäßig bis Gut Dynamischer Serveraufruf verzögert die Ladezeit. Erfordert aufwendiges Caching für Spitzenwerte. |
🟢 Exzellent Reine HTML-Dateien liegen direkt auf dem CDN. Extrem schnelle und weltweit konstante Ladezeiten. |
| Sicherheit (Angriffsfläche) |
🔴 Höheres Risiko Live-Datenbanken, PHP-Laufzeiten und unzählige Plugins bieten permanente Angriffsflächen für Hacker. |
🟢 Minimales Risiko Keine Datenbank, kein PHP auf dem Server. Es gibt für Angreifer schlicht kein direktes System zum Hacken. |
| Wartung & Updates |
🔴 Hoher Aufwand Regelmäßige, kritische Updates für Core, Plugins und Themes sind Pflicht, um Sicherheitslücken zu schließen. |
🟢 Minimaler Aufwand Einmal generiert, läuft die fertige HTML-Seite theoretisch jahrelang wartungsfrei und ohne Sicherheitsrisiko. |
| Hosting & Fixkosten |
🟡 Mittel Benötigt klassischen Webspace oder Server mit PHP/Datenbank. Skalierung bei viel Traffic kostet extra. |
🟢 Sehr niedrig bis Kostenlos Static-Hosting via Cloudflare, Netlify und Co. ist in der Regel permanent gratis oder extrem günstig. |
| Inhaltspflege (Redaktion) |
🟢 Sehr einfach Komfortable visuelle Editoren (WYSIWYG) und Medienbibliotheken. Perfekt für nicht-technische Teams. |
🔴 Komplexer Erfordert standardmäßig Markdown-Dateien oder Git. Ohne technisches Verständnis kaum pflegbar. |
| Vorschau-Funktion |
🟢 Nahtlos im Backend Inhalte können vor der Veröffentlichung direkt per Knopfdruck im Backend-Design geprüft werden. |
🟢 Isolierte Preview-URLs Generiert automatische Test-Links pro Ticket/Änderung. Perfekt für strukturierte Freigabeprozesse. |
| Live-Veröffentlichung |
🟢 Sofort live Nach dem Klick auf "Speichern" ist die Änderung in derselben Sekunde für alle Besucher weltweit sichtbar. |
🟢 Vollautomatisiert Läuft modern und fehlerfrei über eine CI/CD-Pipeline. Der Build-Prozess dauert meist nur wenige Sekunden. |
| Dynamische Features |
🟢 Inklusive Logins, Formulare, Suchen oder Shop-Systeme lassen sich nativ oder per Plugin sofort out-of-the-box nutzen. |
🔴 Aufwendig Benötigt für jedes dynamische Feature externe Drittanbieter, APIs, JavaScript-Frameworks oder Serverless Functions. |
Fazit
- Wann das CMS gewinnt: Ein monolithisches CMS ist oft die bessere Wahl, wenn nicht-technische Teams Inhalte pflegen, eine sofortige Direktbearbeitung gewünscht ist oder die Website stark von nativen, dynamischen Funktionen lebt.
- Wann das SSG gewinnt: Ein modernes SSG-Setup spielt seine Stärken aus, wenn maximale Performance, höchste Sicherheit, minimale Fixkosten und ein automatisierter, ticketbasierter Freigabe-Workflow im Vordergrund stehen.
Am Ende gewinnt kein System pauschal über das andere – es gewinnt immer das Setup, das am besten zu deinem Projekt passt.
~/.cache auf tmpfs zu legen ist auf Desktop-Systemen oft überraschend nützlich. Genau dort landen Browser-Cache, Thumbnails, Build-Reste und anderer Kram, der nach einem Neustart meist nicht wirklich fehlt.
Gerade Browser schreiben permanent kleine Dateien. Allein dadurch kommen viele unnötige Schreibzugriffe zusammen. Wenn ~/.cache im RAM liegt, ist das schneller erledigt und die SSD wird nicht dauernd mit Wegwerfdateien beschäftigt.
tmpfs /home/USERNAME/.cache tmpfs rw,nosuid,nodev,noatime,uid=1000,gid=1000,mode=700 0 0
Pfad, uid und gid musst du an dein System anpassen.
Natürlich ist tmpfs nicht gratis: Der Platz kommt aus dem RAM und nach einem Neustart ist der Cache weg. Aber genau das ist hier meistens eher ein Vorteil als ein Nachteil.
Meine Faustregel: Wenn genug RAM da ist, lohnt sich tmpfs auf ~/.cache fast immer. Schon allein wegen der Browserdateien.
103 Early Hints ist ein HTTP-Status, mit dem der Server dem Browser schon vor der eigentlichen Response wichtige Hinweise schicken kann, z. B. welche CSS- oder Font-Dateien direkt geladen werden sollen.
HTTP/1.1 103 Early Hints
HTTP/1.1 200 OK
Wo hilft das?
Vor allem bei SSR, langsamen Datenbankabfragen oder generell hohem TTFB. Der Browser kann kritische Assets schon anfordern, während das Backend noch an der finalen HTML-Antwort arbeitet.
Wichtig:
Early Hints bringt vor allem etwas für Assets, die du sehr sicher brauchst. Für wechselnde oder unklare Ressourcen ist der Effekt gering oder du preloadest unnötig.
Mit dem Server-Timing HTTP-Header verschickst du Performance-Metriken direkt an den Browser. Diese tauchen sofort im DevTools unter Network → Timings auf.
Format:
Server-Timing: db;dur=123;desc="Query"
In PHP:
$start = microtime(true);
$duration = (microtime(true) - $start) * 1000;
header("Server-Timing: db;dur=$duration;desc=\"Database\"", true);
Live Demo: https://server-timing-hono.deno.dev/ – öffne DevTools, schau in Network → Timing
Statt erst ein riesiges Array aufzubauen, kannst du Werte mit yield einzeln erzeugen und direkt weiterverarbeiten.
function userIds(PDO $db): Generator {
$stmt = $db->query('SELECT id FROM users');
while (($id = $stmt->fetchColumn()) !== false) {
yield (int) $id;
}
}
foreach (userIds($db) as $id) {
processUser($id);
}
Ohne Generatoren landet oft alles zuerst in einem Array, etwa per fetchAll() oder durch manuelles Sammeln. Das kostet bei vielen Datensätzen schnell unnötig viel RAM.
Vorteile: Weniger Speicherverbrauch, schnellerer Start der Verarbeitung, sauberere Trennung zwischen Datenquelle und Verarbeitung.
Wichtig: Generatoren sind ideal für sequentielle Verarbeitung. Wenn du alle Werte mehrfach brauchst oder zufällig darauf zugreifen willst, ist ein echtes Array oft immer noch die richtige Wahl.
Statt berechnete Werte im Code vorzubereiten oder redundant in der DB zu speichern, übernimmt MariaDB/MySQL das selbst:
ALTER TABLE orders
ADD COLUMN gross DECIMAL(10,2) AS (net * (1 + tax_rate)) VIRTUAL;
VIRTUAL bedeutet: kein eigener Speicherplatz – der Wert wird beim Lesen berechnet. Die Alternative STORED schreibt ihn physisch in die Tabelle.
Vorteil: Kein Trigger, kein App-Code, keine Synchronisations-Fehler – die Spalte ist immer korrekt.
Index: Nutzt du die VIRTUAL Column in einer WHERE-Bedingung, lohnt sich ein Index darauf – sonst muss MariaDB/MySQL den Ausdruck für jede Zeile im Scan berechnen:
ALTER TABLE orders ADD INDEX idx_gross (gross);
Der Unterschied ist dramatisch: Abfragen auf großen Tabellen fallen damit von mehreren Sekunden auf wenige Millisekunden – bei mir von 4 Sekunden auf 80 ms. Verwendest du die Spalte hingegen nur im SELECT, ist kein Index nötig: Der Ausdruck wird erst nach dem Filtern berechnet, also nur für die Zeilen, die bereits alle anderen Bedingungen passiert haben.
Eleventy ist das perfekte SSG, wenn du mit Markdown, Nunjucks oder HTML schreiben willst und dir der Build nicht im Weg stehen soll. Du legst ein paar Markdown-Dateien, packst deine Assets daneben und lässt Eleventy rendern. Layouts oder Includes kannst du dazuschalten, aber sie sind optional der ganze Ablauf bleibt minimal.
Probiere es in 2 Schritten aus:
echo "Hello World" > index.md
npx @11ty/eleventy
Das Problem: WebP spart ~30% Bandbreite gegenüber JPEG, findet aber wenig Anwendung.
Warum nicht mehr Websites WebP nutzen:
- Unwissenheit – Viele kennen WebP gar nicht
- Kompatibilität-Angst – "Was wenn alte Browser nicht unterstützen?" (Fallback ist einfach!)
- Workflow-Trägheit – Bestehendes Tooling müsste angepasst werden
- Wahrnehmung – Mythos: PNG/JPEG hätten bessere Qualität (stimmt nicht!)
<picture>
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Fallback">
</picture>
Browser-Support: 97%+ der modernen Browser. Kein Grund mehr zu warten!
Meine Faustregel: WebP für neue Projekte, schrittweise Migration für bestehende.
Die Idee: Wenn du mehrere Bedingungen mit || kombiniertst, stoppt PHP sobald eine wahr ist (Short-Circuit-Evaluation). Ordne deine Checks strategisch:
if ($this->expensiveDbQuery() || $variable === '123') { }
if ($variable === '123' || $this->expensiveDbQuery()) { }
Erspart dir eine ganze DB-Abfrage, wenn die erste Bedingung passt. Mit && funktioniert es genauso – auch hier sollten billige Checks zuerst kommen.
Faustregel: Billige Operationen zuerst, teure Operationen zuletzt – das gilt für beide || und &&. So einfach ist Leistungsoptimierung!