Lorsque nous avons entrepris de reconstruire le site de Basi Software, le choix évident était Next.js. Nous l’utilisons constamment sur les projets clients. L’équipe le connaît par cœur.
Nous avons choisi Astro à la place. Voici pourquoi — et ce que nous en avons appris.
La taxe SPA
Les applications monopage (SPA) ont déplacé la charge de rendu du serveur vers le client. Pour des applications hautement interactives — tableaux de bord, éditeurs, outils collaboratifs — c’est le bon compromis. Pour un site vitrine avec un formulaire de contact, c’est une taxe.
Cette « taxe SPA » se manifeste par :
- Du JavaScript livré pour des interactions qui ne se produisent jamais — l’utilisateur lit le hero, fait défiler la page, part. Il n’a jamais cliqué sur le déclencheur de la modale. Mais vous avez quand même livré le JS de la modale.
- Des cascades d’hydratation — React réhydrate l’arbre entier avant qu’aucune interaction ne soit possible
- Un décalage de mise en page — le HTML rendu côté serveur est remplacé par du HTML rendu côté client, provoquant du CLS
# Lighthouse sur notre ancien site Next.js (build de production)
Performance : 71
First Contentful Paint : 1,8 s
Total Blocking Time : 340 ms
Bundle JavaScript : ~280 ko (gzippé)
# Après la migration vers Astro
Performance : 98
First Contentful Paint : 0,6 s
Total Blocking Time : 0 ms
Bundle JavaScript : ~6 ko (uniquement les îlots Nav et ContactForm)
Ce que signifie réellement l’architecture en îlots d’Astro
Le terme « îlots » a été inventé par Katie Sylor-Miller d’Etsy. L’idée : une page par ailleurs statique comporte des « îlots » isolés d’interactivité. Chaque îlot s’hydrate indépendamment. Tout le reste est livré en HTML sans JS.
---
// Layout.astro — la coquille est du HTML pur
import Nav from '../components/Nav.astro'; // Coquille statique + petit script
import ContactForm from './ContactForm'; // Îlot React
import HeroSection from './HeroSection.astro'; // Zéro JS — HTML statique
---
<body>
<!-- Composant Astro — aucun runtime de framework requis -->
<Nav />
<main>
<!-- Composant Astro statique — livré en HTML, coût d'exécution nul -->
<HeroSection />
</main>
</body>
Le formulaire de contact est le seul îlot de framework ici. La navigation conserve son comportement interactif grâce à un petit script navigateur, sans faire entrer React sur chaque page.
Les directives qui comptent
Astro expose cinq directives d’hydratation. Choisir la bonne a un impact mesurable :
| Directive | Quand elle s’hydrate | À utiliser pour |
|---|---|---|
client:load | Immédiatement | Navigation, éléments interactifs au-dessus de la ligne de flottaison |
client:idle | Quand le navigateur est inactif | Composants en dessous de la ligne de flottaison |
client:visible | Quand l’élément entre dans le viewport | Composants chargés à la demande |
client:media | Quand une media query correspond | Widgets mobile uniquement |
client:only | Côté client uniquement, pas de SSR | Composants dépendant d’API navigateur |
Pour la plupart des sites vitrines, client:visible est le bon choix par défaut pour tout ce qui se trouve sous la ligne de flottaison.
Des transitions de vue sans framework
L’une des raisons pour lesquelles les équipes se tournent vers Next.js est son routeur intégré avec transitions de page. Astro propose également cela, via le composant <ClientRouter /> et la View Transitions API.
---
import { ClientRouter } from 'astro:transitions';
---
<head>
<ClientRouter />
</head>
/* Transition personnalisée — s'exécute à chaque navigation de page */
::view-transition-old(root) {
animation: fade-out 0.3s ease-in forwards;
}
::view-transition-new(root) {
animation: slide-up 0.4s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
L’attribut transition:persist sur le Nav signifie qu’il ne se remonte pas entre les pages — l’îlot React reste actif, en conservant la position de défilement et l’état ouvert/fermé.
Des collections de contenu pour un contenu type-safe
Ce blog est lui-même propulsé par les collections de contenu d’Astro — une couche de contenu validée par Zod et pensée pour TypeScript :
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
category: z.string(),
tags: z.array(z.string()).default([]),
}),
});
export const collections = { blog };
Chaque fichier MDX dans src/content/blog/ est désormais entièrement typé. Si un article n’a pas un champ requis, le build échoue — et non une erreur en production.
Quand privilégier encore Next.js
Astro n’est pas la réponse à tout :
- Applications hautement interactives — si la majorité de la page doit être réactive, livrez React. Un site Astro avec
client:loadsur chaque composant est pire que Next.js. - Fonctionnalités temps réel — tableaux de bord en direct, édition collaborative, interfaces intensives en websockets relèvent d’une véritable SPA
- Grandes applications authentifiées — flux d’authentification, routage dynamique selon les données utilisateur, état client complexe — Next.js l’emporte ici
L’heuristique : si la plupart de vos pages sont surtout lues plutôt que manipulées, Astro est le meilleur point de départ.
Conclusion
Le retour à l’architecture multi-pages n’est pas un retour en arrière. C’est la reconnaissance que le modèle natif du web — des documents reliés par des hyperliens — reste l’architecture la plus performante, la plus accessible et la plus résiliente pour les sites orientés contenu.
Astro rend simplement agréable de construire ainsi en 2026.