WordPress naar Astro: Hoe we Lighthouse 100 behaalden bij onze rebuild
Laten we eerlijk zijn: onze oude WordPress-site was beschamend. Niet omdat deze er slecht uitzag — het zag er eigenlijk behoorlijk goed uit. Maar onder de motorkap? Een Time to Interactive van 3,2 seconden, een Lighthouse-performancescore rond de 58, en een stapel plugins die elk deployement voelde als het ontmantelen van een bom. Wij zijn een webontwikkelingsbureau. Wij bouwen snelle sites voor klanten. En onze eigen site was... niet snel.
Dus hebben we het afgebroken en herbouwd met Astro. Het resultaat: perfecte scores van 100 in alle vier Lighthouse-categorieën — Performance, Accessibility, Best Practices en SEO. Niet op een enkele pagina. Op elke pagina. Dit is het verhaal van hoe we daar zijn gekomen, wat er fout liep, en wat we anders zouden doen.
Inhoudsopgave
- Waarom we WordPress hebben verlaten
- Waarom we Astro hebben gekozen
- De migratiestrategje
- Architectuurbeslissingen die het verschil maakten
- Performance-optimalisaties diepgaand
- Het Lighthouse 100-scorekaart
- Voor en na: De cijfers
- Wat we onderweg fout hebben gedaan
- Lessen voor uw eigen migratie
- Veelgestelde vragen

Waarom we WordPress hebben verlaten
Kijk, WordPress wordt gebruikt door zo'n 43% van het web. Het is geen slecht platform. We hebben veel WordPress-sites voor klanten gebouwd en zullen dat blijven doen als het de juiste keuze is. Maar voor onze eigen bureau-site — een meestal-statische marketingsite met een blog — was WordPress overkill in de ergste zin.
Zo zag onze WordPress-setup eruit:
- Theme: Custom theme gebouwd op Sage (Roots.io)
- Plugins: 14 actieve plugins, waaronder Yoast SEO, WP Rocket, Advanced Custom Fields Pro, Gravity Forms en een aantal anderen
- Hosting: WP Engine Professional plan voor $60/maand
- CDN: Cloudflare Pro voor $20/maand
- Build-complexiteit: PHP-templating, Webpack voor assets, MySQL-database
Zelfs met WP Rocket die agressief cachete, waren onze Core Web Vitals middelmatig. De Largest Contentful Paint (LCP) was 2,4 seconden op mobiel. Cumulative Layout Shift (CLS) was 0,12 — niet verschrikkelijk, maar niet goed. En elke keer dat we een plugin bijwerkten, bestond er een reële kans dat iets zou kapotgaan.
Het echte probleem? We betaalden $80/maand aan hostingkosten voor een site die misschien 3.000 bezoeken per maand kreeg. Dat is niet veel verkeer, en dat is veel geld voor wat eigenlijk een brochuresite met een blog was.
Het brekende punt
De druppel die de emmer deed overlopen kwam in januari 2025. Een WordPress-kernupdate brak onze aangepaste Gutenberg-blokken. Het repareren vereiste het bijwerken van ACF Pro, wat het bijwerken van onze thema's PHP-versiecompatibiliteit vereiste, wat het bijwerken van de hostingomgeving vereiste. Wat een routinematige update zou moeten zijn, werd een volledige dag werk.
Ik keek naar ons team en zei: "We vertellen klanten om headless te gaan. Waarom volgen we onszelf niet op?"
Waarom we Astro hebben gekozen
We evalueerden vier opties voor de herbouw:
| Framework | Voordelen | Nadelen | Ons oordeel |
|---|---|---|---|
| Next.js | We kennen het goed, geweldige ecosysteem | Overkill voor een content-site, vereist server of edge runtime | Te zwaar |
| Astro | Content-gericht, stuurt standaard nul JS, island-architectuur | Kleinere ecosysteem, nieuwer | Perfect geschikt |
| Eleventy | Eenvoudig, snelle builds, volwassen | Beperkt componentmodel, minder moderne DX | Tweede keuze |
| Hugo | Extreem snelle builds, enkele binary | Go-templating is vervelend, beperkte flexibiliteit | Niet voor ons |
We bouwen veel Next.js-projecten voor klanten, en het is onze standaardkeuze voor alles met dynamische functionaliteit. Maar voor een content-zware marketingsite? Next.js stuurt een JavaScript-runtime naar de browser ongeacht of je die nodig hebt. Zelfs met statische export, verstuur je React naar de browser.
Astro's filosofie sprak tot ons: stuur HTML, voeg JavaScript alleen toe waar je het nodig hebt. Hun island-architectuur betekent dat je een volledig interactieve React-component naast volkomen statische HTML kunt hebben, en de statische delen versturen nul JavaScript. Dat was precies wat we nodig hadden.
We hadden ook meer Astro-ontwikkelingswerk voor klanten gedaan in 2024, dus het team was vertrouwd met het framework. Het was geen leerexercitie — het was een tool die we al vertrouwden.
De Content Layer-vraag
Een beslissing die we vroeg namen: we gingen geen headless CMS voor onze eigen site gebruiken. Voor clientprojecten raden we vaak headless CMS-setups aan met Contentful, Sanity of Storyblok. Maar voor onze blog, waar elke auteur een ontwikkelaar is die vertrouwd is met Markdown en Git? Content Collections in Astro met MDX-bestanden gecommit naar de repo was eenvoudiger en sneller.
Geen API-calls op buildtijd. Geen content delivery network voor content. Geen extra service om te beheren of voor te betalen. Gewoon bestanden in een map.
De migratiestrategje
We hebben geen big-bang migratie gedaan. Dit is onze gefaseerde aanpak:
Fase 1: Content Audit (1 week)
We exporteerden alle WordPress-content met wp-cli en converteren posts naar MDX met een aangepast script gebouwd met turndown (HTML-naar-Markdown-converter) plus wat regex-opruiming. We hadden op dat moment 47 blogberichten. Ongeveer 12 daarvan waren verouderd of slecht presterende, dus we verwezen die door naar relevante nieuwere content en migreerden ze niet.
Fase 2: Design System in Astro (2 weken)
We herbouwden onze componentenbibliotheek als Astro-componenten. Knoppen, kaarten, sectielayouts, navigatie — allemaal als .astro-bestanden. Geen framework nodig voor één ervan. Zuivere HTML en CSS met bereikstijlen.
Fase 3: Page Build (2 weken) Startpagina, mogelijkhedenpagina's, over, contact, bloglijst, individuele blogberichten, 404. We bouwden ze allemaal als Astro-pagina's met onze componentenbibliotheek.
Fase 4: Performance Tuning (1 week) Dit is waar het Lighthouse 100-werk echt gebeurde. Meer hieronder.
Fase 5: Launch en Redirect (2 dagen) We stelden juiste 301-redirects in voor elke oude URL, verifieerden met Screaming Frog dat niets kapot was, dienden de nieuwe sitemap in bij Google Search Console, en wisselden DNS.
Totale tijdlijn: ongeveer 6 weken parttime werk naast clientprojecten.

Architectuurbeslissingen die het verschil maakten
Nul JavaScript standaard
Onze hele site stuurt ongeveer 2KB JavaScript totaal. Dat is geen typfout. Twee kilobytes. En het meeste daarvan is een klein script voor mobiele navigatieomschakeling en analytics.
Dit is onze mobiele nav — geen framework, geen afhankelijkheden:
---
// MobileNav.astro
---
<button id="menu-toggle" aria-expanded="false" aria-controls="mobile-menu">
<span class="sr-only">Toggle menu</span>
<svg><!-- hamburger icon --></svg>
</button>
<nav id="mobile-menu" hidden>
<slot />
</nav>
<script>
const toggle = document.getElementById('menu-toggle');
const menu = document.getElementById('mobile-menu');
toggle?.addEventListener('click', () => {
const expanded = toggle.getAttribute('aria-expanded') === 'true';
toggle.setAttribute('aria-expanded', String(!expanded));
menu?.toggleAttribute('hidden');
});
</script>
Die <script>-tag in een Astro-component wordt automatisch gebundeld en gededupliceerd. Het is klein, het is vanilla JS, en het werkt overal.
CSS-strategie: Bereikstijlen + Een minimale globale laag
We gebruikten Astro's ingebouwde bereikstijlen voor stijlen op componentniveau en een enkele globale stylesheet (ongeveer 8KB geminificeerd) voor typografie, reset, aangepaste eigenschappen en utility-klassen. Geen Tailwind. Controversieel standpunt, ik weet het.
We houden van Tailwind voor grotere applicaties en clientprojecten. Maar voor een site van deze grootte voegde het buildcomplexiteit en bestandsgrootte toe die we niet nodig hadden. Onze handgeschreven CSS is kleiner dan Tailwind's output zou zijn, zelfs met purging.
/* Global custom properties */
:root {
--color-text: #1a1a2e;
--color-bg: #ffffff;
--color-accent: #e94560;
--color-accent-dark: #c81e45;
--font-body: 'Inter', system-ui, sans-serif;
--font-heading: 'Cal Sans', var(--font-body);
--max-width: 72rem;
--space-unit: 0.25rem;
}
Statische generatie met slimme preloading
Elke pagina wordt statisch gegenereerd op buildtijd. We gebruiken Astro's ingebouwde prefetch-integratie om links vooruit te laden bij hover, waardoor navigatie voelt als instant:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://socialanimal.dev',
integrations: [mdx(), sitemap()],
prefetch: {
prefetchAll: false,
defaultStrategy: 'hover',
},
build: {
inlineStylesheets: 'auto',
},
});
Performance-optimalisaties diepgaand
Het behalen van Lighthouse 100 gaat niet alleen over het kiezen van het juiste framework. Astro geeft je een voorstart, maar de laatste 10-15 punten vereisen doelbewuste inspanning. Dit is wat we hebben gedaan.
Afbeeldingsoptimalisatie
Astro's ingebouwde <Image />-component handelt responsieve afbeeldingen af met automatische formaatconversie (WebP/AVIF), lazy loading, en juiste width/height-attributen om CLS te voorkomen.
---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---
<Image
src={heroImage}
alt="Social Animal development team working on headless architecture"
widths={[400, 800, 1200]}
sizes="(max-width: 600px) 400px, (max-width: 900px) 800px, 1200px"
format="avif"
fallbackFormat="webp"
quality={80}
loading="eager"
/>
Voor de heroafbeelding specifiek gebruiken we loading="eager" omdat deze boven de vouw staat. Alles anders krijgt standaard loading="lazy".
We gingen ook alle afbeeldingen op de site door en vroegen: "Moet dit een afbeelding zijn?" Enkele decoratieve elementen werden CSS-verlopen of SVG's. Onze heliosectie-achtergrond is bijvoorbeeld een CSS-verloop met een subtiele ruisstructuur toegepast via een klein inline SVG.
Lettertype-laadstrategie
Lettertypen zijn een Lighthouse-killer. Dit is onze aanpak:
Host alles zelf. Geen Google Fonts CDN. We hebben Inter en Cal Sans gedownload en serveren ze vanaf ons eigen domein. Dit elimineert een DNS-lookup, TCP-verbinding en TLS-handshake naar fonts.googleapis.com.
Agressief subset. We gebruikten
glyphhangerom te analyseren welke karakters we werkelijk gebruiken, en settten vervolgens onze lettertypen onder metpyftsubset. Onze Inter Regular WOFF2 ging van 96KB naar 18KB.Gebruik
font-display: swapmet een zorgvuldig gekozen system font fallback die statistieken goed aansluit, waardoor layoutverandering tijdens swap wordt geminimaliseerd.Preload de kritieke lettertypebestanden:
<link rel="preload" href="/fonts/inter-latin-400.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/cal-sans-latin-600.woff2" as="font" type="font/woff2" crossorigin />
Hosting: Cloudflare Pages
We zijn verhuisd van WP Engine ($60/maand) naar Cloudflare Pages (gratis plan). Ja, gratis. Onze site zit goed binnen de limieten van Cloudflare's gratis plan — 500 builds per maand, onbeperkte bandbreedte, onbeperkte verzoeken.
Cloudflare Pages deployt vanaf een Git push, serveert vanaf hun wereldwijd edge netwerk, en handelt cache headers automatisch af. Buildtijden gemiddeld 22 seconden voor onze hele site. Vergelijk dat met onze WordPress-setup waar een cache-zuivering alleen langer kon duren.
Maandelijkse hostingkosten zijn gedaald van $80 naar $0.
Critical CSS Inlining
Astro inline automatisch kleine stylesheets wanneer je build.inlineStylesheets: 'auto' instelt. Voor onze pagina's, elke kritieke stijl is inline in de <head>, wat betekent dat er nul render-blokkerende CSS-verzoeken zijn. De browser kan onmiddellijk beginnen te tekenen.
Derde-partij script discipline
Dit is waar de meeste sites hun perfecte scores verliezen. Elk derde-partij script is een potentieel performance-ramp. We limiteerden de onze genadeloos:
- Analytics: Overgeschakeld van Google Analytics (70KB+ JavaScript) naar Plausible Analytics (< 1KB script, async geladen). We betalen $9/maand voor Plausible, en de datakwaliteit is eigenlijk beter voor onze behoeften.
- Formulieren: Ons contactformulier op /contact gebruikt een eenvoudig HTML-formulier met serverhandeling via Cloudflare Pages Functions. Geen JavaScript-formulierenbibliotheek.
- Geen chatwidgets. Geen social media-insluitingen. Geen cookie-consentbanners (we gebruiken geen cookies die toestemming vereisen).
Het Lighthouse 100-scorekaart
Dit zijn onze werkelijke Lighthouse-scores per mei 2025, gemeten met Chrome DevTools op een vertragde verbinding (standaard mobiele Lighthouse-simulatie):
| Metriek | Score |
|---|---|
| Performance | 100 |
| Accessibility | 100 |
| Best Practices | 100 |
| SEO | 100 |
| First Contentful Paint | 0,6s |
| Largest Contentful Paint | 0,8s |
| Total Blocking Time | 0ms |
| Cumulative Layout Shift | 0 |
| Speed Index | 0,8s |
De Total Blocking Time van 0ms is mijn favoriete statistiek. Nul. Er is eigenlijk geen JavaScript dat de main thread blokkeert. Ooit.
Voor en na: De cijfers
| Metriek | WordPress (Voor) | Astro (Na) | Verbetering |
|---|---|---|---|
| Lighthouse Performance | 58 | 100 | +72% |
| LCP (mobiel) | 2,4s | 0,8s | 3x sneller |
| CLS | 0,12 | 0 | Geëlimineerd |
| TBT | 380ms | 0ms | Geëlimineerd |
| Paginagewicht (startpagina) | 1,8MB | 142KB | 92% kleiner |
| HTTP-verzoeken | 47 | 6 | 87% minder |
| JavaScript verzonden | 340KB | 2KB | 99,4% minder |
| Maandelijkse hostingkosten | $80 | $9 (alleen Plausible) | 89% goedkoper |
| Build/deploy-tijd | 3-5 min | 22 sec | ~10x sneller |
| Time to first byte | 420ms | 18ms | 23x sneller |
De paginagewichtreductie is zelfs voor ons verbijsterend. 1,8MB naar 142KB. Dat is wat gebeurt wanneer je jQuery, React, WP Rocket's scriptlader, Yoast's schema markup-injector en veertien plugin-stylesheets stopt met versturen.
Wat we onderweg fout hebben gedaan
Het was niet allemaal soepel verlopen. Eerlijkheid nu.
Fout 1: We hebben inhoudbeheer bijna over-engineered
Onze eerste instinct was om Sanity in te stellen als een headless CMS voor de blog. We brachten twee dagen door met het configureren van schema's en het instellen van Sanity Studio voordat we achteruit stapten en vroegen: "Wie gaat dit werkelijk gebruiken?" Het antwoord was... ons. Ontwikkelaars. Die volkomen blij zijn met het schrijven van MDX in VS Code. We scheuren Sanity eruit en gingen met Astro Content Collections. Spaarde voortdurende kosten en complexiteit.
Fout 2: Lettertype-subsetting brak speciale karakters
Onze initiële lettertype-subset was te agressief. We strookten karakters weg waarvan we dachten dat we ze nooit zouden gebruiken, publiceerden toen een blogbericht met een em-dash en een paar gekrulde aanhalingstekens die als vakjes weergegeven werden. Les: test uw subsets met echte inhoud, niet alleen "ABCDEFG".
Fout 3: We zijn OpenGraph-afbeeldingen vergeten
We lanceerden zonder dynamische OG-afbeeldingen. Wanneer iemand een blogbericht op Twitter/X of LinkedIn deelde, toonde het een generieke terugval. We moesten terugkeren en een OG-afbeelding generatiepijplijn bouwen met @astrojs/og (die Satori onder de motorkap gebruikt). Had in de originele scope moeten zijn.
Fout 4: De 301-redirectkaart had gaten
Ondanks het gebruik van Screaming Frog voor het in kaart brengen van oude URL's, misten we een aantal afbeeldings-URL's waarvan externe sites hotlinks waren. We vingen deze in Cloudflare's analytics ongeveer een week na lancering en voegden de ontbrekende omleidingen toe. Controleer altijd uw serverlogboeken na een migratie — Google Search Console zal niet alles vangen.
Lessen voor uw eigen migratie
Als u overweegt om van WordPress naar een statisch-first framework over te stappen, dit is wat ik u zou vertellen:
Controleer voor u migreert. Dood inhoud die niet goed presteerde. Een migratie is een geweldige gelegenheid om in te snoeien.
Match het gereedschap aan de taak. Astro was perfect voor ons omdat we meestal inhoud hebben. Als u zware interactiviteit nodig hebt, Next.js of een vergelijkbaar framework kan de betere keuze zijn.
Vervoer niet je oude architectuur. We probeerden onze WordPress-setup niet in Astro na te bootsen. We hebben alles van voren af aan opnieuw bedacht. Hebben we werkelijk een formulierplugin nodig? Nee, een
<form>-element met een serverloos functie werkt prima.Meet voor, meet na, meet voortdurend. We stelden een Lighthouse CI-taak in GitHub Actions in die op elke pull-aanvraag wordt uitgevoerd. Als een PR een score onder de 95 laat zakken, faalt de check.
Budget voor de "laatste 5%". Het gaat van Lighthouse 85 naar 95 is eenvoudig. Van 95 naar 100 gaan vereist lettertype-subsetting, critical CSS-analyse, afbeeldingsformaatoptimalisatie en derde-partij script-controle. Plan tijd ervoor.
Uw hostingkosten moeten uw oude setup beschamen. Als u statische bestanden serveert en nog steeds aanzienlijke hostingkosten betaalt, klopt iets niet. Statische hosting is tegenwoordig een commodity.
Als u geïnteresseerd bent in hoe een migratie als deze voor uw project zou uitzien, bekijk onze prijzenpagina of neem contact op. We hebben dit migratiepad nu voor verschillende klanten gedaan, en de performance-winsten zijn consistent dramatisch.
Veelgestelde vragen
Hoe lang duurt het om een WordPress-site naar Astro te migreren? Voor onze site (ongeveer 50 pagina's inclusief blogberichten) duurde het ruwweg 6 weken parttime werk. Een grotere site met honderden berichten en complexe aangepaste posttypen kan 8-12 weken duren. De werkelijke ontwikkeling is meestal sneller dan de content audit en redirect mapping.
Kunt u Lighthouse 100 bereiken met Next.js in plaats van Astro? Het is mogelijk maar aanzienlijk moeilijker. Next.js stuurt een JavaScript-runtime naar de browser zelfs voor statische pagina's (de React-hydratielaag). U kunt dicht benaderen — scores van 95-99 zijn haalbaar met voorzichtige optimalisatie. Maar Astro's nul-JS-standaard aanpak maakt perfecte scores veel eenvoudiger bereikbaar voor content-sites.
Wat doen we met WordPress-functies zoals contactformulieren en zoeken? Contactformulieren werken prima met gewone HTML-formulieren en een serverloze functie-backend (Cloudflare Pages Functions, Netlify Functions, enz.). Voor zoeken gebruiken we een client-side zoeken met Pagefind, die een zoekindex op buildtijd maakt en slechts 5KB JavaScript stuurt. Het is snel en werkt offline.
Doet het migreren van WordPress naar Astro SEO pijn? Nee, zolang je het correct afhandelt. We stelden 301-omleidingen in voor elke URL, behielden onze URL-structuur waar mogelijk, dienden een nieuwe sitemap in en hielden al onze gestructureerde gegevens. Ons organische verkeer nam eigenlijk 23% toe in de drie maanden na migratie, waarschijnlijk vanwege verbeterde Core Web Vitals.
Hoe gaat u om met dynamische inhoud zoals opmerkingen op een Astro-site? We hebben geen opmerkingen op onze blog — ze waren meestal spam op WordPress toch. Als u opmerkingen nodig hebt, werken services zoals Giscus (op GitHub Discussions gebaseerd) of Hyvor Talk goed als ingebedde componenten. Ze laden als Astro-eilanden, dus ze beïnvloeden niet de initiële paginabelasting.
Is Astro productierijp voor grote sites? Absoluut. Astro 5.x (uitgebracht eind 2024) is volwassen en stabiel. Bedrijven als Porsche, Google, Microsoft en Netlify gebruiken het in productie. De buildprestaties schalen ook goed — sites met duizenden pagina's bouwen in minder dan een minuut met de juiste configuratie.
Hoe ziet het voortdurende onderhoud eruit vergeleken met WordPress? Dramatisch minder. Geen plugin-updates, geen databaseonderhoud, geen beveiligingspatches voor PHP. We werken Astro en zijn afhankelijkheden ongeveer eenmaal per maand bij via Dependabot PR's. Elke update kost ongeveer 5 minuten om te controleren en samen te voegen. Vergelijk dat met de WordPress-updateloopband.
Kunnen niet-technische teamleden nog steeds inhoud op een Astro-site bewerken? Met onze setup (MDX-bestanden in Git) moet je vertrouwd zijn met Markdown en eenvoudige Git-workflows. Voor teams met niet-technische editors raden we aan Astro te koppelen aan een headless CMS zoals Sanity, Contentful of Storyblok. De editors krijgen een visuele interface en u krijgt nog steeds alle performance-voordelen van statische generatie.