Das Problem mit der React-SPA
Die erste Version von rypox.de war eine React Single-Page Application. Technisch funktional, aber mit Problemen, die sich mit der Zeit nicht verbesserten, sondern verschärften:
- SEO war mangelhaft, Suchmaschinen-Crawler hatten Schwierigkeiten mit Client-Side Rendering. Trotz Workarounds wie
react-helmetund Pre-Rendering blieben die Ergebnisse unbefriedigend - Initial Load war langsam, Das JavaScript-Bundle umfasste über 400 KB (gzipped). Für eine primär statische Website mit Blog und Unternehmensseiten war das unverhältnismäßig
- Lighthouse-Scores waren mittelmäßig, Performance um 60-70, LCP über 3 Sekunden auf mobilen Geräten
- Hydration-Overhead, React musste die gesamte Seite im Browser “hydrieren”, obwohl 90% des Inhalts statisch war
Die Entscheidung fiel: Wir brauchen ein Framework, das statische Inhalte als statisches HTML ausliefert und JavaScript nur dort einsetzt, wo es tatsächlich benötigt wird.
Warum Astro
Astro verfolgt einen radikal anderen Ansatz als React, Next.js oder Gatsby: Zero JavaScript by Default. Jede Seite wird zur Build-Zeit als statisches HTML gerendert. JavaScript wird nur explizit und gezielt eingebunden, als sogenannte “Islands”.
Core Principles
| Prinzip | Beschreibung |
|---|---|
| Zero JS by Default | Kein JavaScript im Browser, solange nicht explizit angefordert |
| Islands Architecture | Interaktive Komponenten als isolierte “Inseln” in statischem HTML |
| UI-agnostisch | React, Vue, Svelte, Solid, jedes Framework als Island verwendbar |
| Content First | Optimiert für content-lastige Websites: Blogs, Docs, Marketing |
| Edge-Ready | Static Output oder Server-Side Rendering, deploybar auf jeder Plattform |
Der Unterschied in Zahlen
| Metrik | React-SPA (vorher) | Astro (nachher) |
|---|---|---|
| JS Bundle Size | ~420 KB (gzipped) | ~12 KB (nur Islands) |
| Initial Load (3G) | ~4.2s | ~0.8s |
| Lighthouse Performance | 62 | 100 |
| Lighthouse SEO | 78 | 100 |
| Lighthouse Accessibility | 85 | 100 |
| Time to Interactive | ~3.8s | ~0.9s |
| Build Time | ~45s | ~3s |
Content Collections für den Blog
Astros Content Collections sind der Grund, warum diesen Blog überhaupt zu pflegen Spaß macht. Markdown-Dateien mit Frontmatter werden typsicher verwaltet, inklusive Schema-Validierung:
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blogCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
date: z.date(),
author: z.string(),
tags: z.array(z.string()),
image: z.string().optional(),
}),
});
export const collections = {
blog: blogCollection,
};
Jeder Blogartikel wird beim Build gegen dieses Schema validiert. Ein fehlender Titel oder ein falsches Datumsformat führt zu einem Build-Fehler, nicht zu einer kaputten Seite in Produktion.
Querying
---
// src/pages/blog/index.astro
import { getCollection } from 'astro:content';
const posts = (await getCollection('blog'))
.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf());
---
<ul>
{posts.map(post => (
<li>
<a href={`/blog/${post.slug}/`}>
<h2>{post.data.title}</h2>
<time>{post.data.date.toLocaleDateString('de-DE')}</time>
</a>
</li>
))}
</ul>
Kein GraphQL, kein CMS-API-Call, keine Laufzeit-Datenbank. Markdown-Dateien im Repository, typsicher gequeried zur Build-Zeit.
Islands Architecture, React als Insel
Nicht alles auf rypox.de ist statisch. Die TechSphere-Visualisierung auf der Startseite ist eine WebGL-Komponente, gebaut mit React Three Fiber. In Astro wird sie als Island eingebunden:
---
import TechSphere from '../components/TechSphere';
---
<section class="hero">
<h1>Softwarearchitektur für den Finanzsektor</h1>
<TechSphere client:visible />
</section>
client:visible bedeutet: Die React-Komponente wird erst geladen und hydriert, wenn sie in den Viewport scrollt. Vorher wird kein Byte JavaScript für diese Komponente übertragen.
Hydration-Strategien
| Directive | Verhalten | Use Case |
|---|---|---|
client:load | Sofort beim Seitenaufruf | Kritische interaktive Elemente |
client:idle | Nach dem Laden, wenn Browser idle | Nicht-kritische Interaktivität |
client:visible | Wenn Komponente in Viewport scrollt | Below-the-fold Inhalte |
client:media | Wenn Media Query zutrifft | Responsive Interaktivität |
client:only | Nur Client-Side, kein SSR | Reine Client-Komponenten (z.B. WebGL) |
Für die TechSphere verwenden wir client:visible, weil die 3D-Visualisierung auf der Startseite erst relevant wird, wenn der Nutzer sie sieht. Das spart bei Mobile-Nutzern, die nicht bis zur Visualisierung scrollen, den kompletten Download des Three.js-Bundles. Dummerweise wird sie bei uns gleich am Anfang der Seite eingesetzt. Im konkreten Fall wird sie also doch sofort geladen, aber in der Theorie stimmt es.
Build Performance
Astro baut schnell. Die gesamte rypox.de Website, Blog, Unternehmensseiten, Komponenten, baut in unter 3 Sekunden. Das klingt trivial, hat aber praktische Auswirkungen:
- Schnelles Feedback, Änderungen am Blog sind in Sekunden live in der Preview
- CI/CD, Der Build-Schritt in der Pipeline ist vernachlässigbar
- Content-Workflow, Autoren können Markdown-Dateien pushen und sehen das Ergebnis fast sofort
Vite als Build Tool
Astro nutzt Vite unter der Haube. Hot Module Replacement im Dev-Server ist quasi instantan. Das ist ein drastischer Unterschied zu Webpack-basierten React-Setups, wo nach jeder Änderung Sekunden vergehen.
llms.txt für KI-Discoverability
Ein Nebeneffekt der Migration, der sich als strategisch relevant herausgestellt hat: Astro macht es einfach, maschinenlesbare Metadaten bereitzustellen. Wir haben eine llms.txt-Datei implementiert, ein aufkommendes Format, das KI-Systemen strukturierte Informationen über eine Website bereitstellt.
# rypox GmbH
> Softwarearchitektur und Entwicklung für den Finanzsektor
## Kernkompetenzen
- Zahlungsverkehr (VoP, SEPA, ISO 20022)
- Clean Architecture und Domain-Driven Design
- Microservices mit Spring Boot und Kubernetes
## Blog
- /blog/verification-of-payee/
- /blog/kafka-echtzeit-transaktionen/
- /blog/java-21-virtual-threads/
In einer Welt, in der immer mehr Informationen über KI-Assistenten abgerufen werden, ist die maschinenlesbare Aufbereitung der eigenen Inhalte keine Spielerei, sondern vorausschauende Content-Strategie.
Deployment
Das Deployment ist denkbar einfach: Astro generiert statische HTML-Dateien, die auf jedem Webserver laufen. In unserem Fall deployen wir auf einen einfachen Nginx, kein Node.js-Server, kein CDN-Setup notwendig (auch wenn ein CDN natürlich sinnvoll ist).
npm run build # Generiert dist/
# dist/ enthält reines HTML, CSS und minimales JS
Was wir vermissen
Fairness halber: Astro ist nicht perfekt für jeden Anwendungsfall.
- Keine Client-Side Navigation, Jeder Seitenaufruf ist ein vollständiger Page Load. Für eine Content-Website akzeptabel, für eine Web-App nicht
- Ökosystem kleiner als React/Next.js, Weniger Third-Party-Komponenten und Tutorials
- View Transitions noch in Entwicklung, Astros View Transitions API verbessert sich, erreicht aber nicht die Flüssigkeit einer SPA-Navigation
Für rypox.de, eine Unternehmenswebsite mit Blog und technischen Inhalten, überwiegen die Vorteile bei weitem.
Fazit
Die Migration von React-SPA zu Astro war eine der besten technischen Entscheidungen für rypox.de. Perfekte Lighthouse-Scores, minimales JavaScript, schnelle Builds und ein Content-Workflow, der auf Markdown und Git basiert. Astro löst genau das Problem, das wir hatten: Eine Website, die primär Inhalte ausliefert, braucht kein 400-KB-JavaScript-Framework. Sie braucht gutes HTML und gezieltes JavaScript dort, wo es tatsächlich Interaktion gibt.