Tous les articles

Migrer 15 ans de WordPress vers Astro — et ce que cache un 100/100 Lighthouse

Le site que vous lisez vient de changer de moteur. Pendant quinze ans, one-day.fr a tourné sous WordPress ; il est désormais généré avec Astro 5 et servi depuis Cloudflare Pages. Il y a une forme de cohérence à ce que ce soit ce site, plutôt qu’un site client, qui raconte l’opération de bout en bout — avec les vrais chiffres, la vraie méthode, et les endroits où le résultat mérite d’être lu avec méfiance.

Parce que oui, l’histoire finit sur un 100/100 mobile et desktop. Mais si je m’arrêtais au score, je vous vendrais la même chose que tous les articles « WordPress vs Astro » du web — ceux qui migrent un site jouet de trois pages pour prouver un point déjà connu. Ce qui suit est l’inverse : une migration de quinze ans de contenu réel, avec un tri éditorial assumé, et une lecture critique de ce qu’un score parfait mesure vraiment.

Un point à poser d’emblée, parce qu’il court sous tout le reste : la stack n’était pas le problème. Elle était le plafond.

Le point de départ — un WordPress qui n’avait pas à rougir

Commençons par les scores avant, pour désamorcer le procès facile. Le WordPress de one-day.fr affichait 87 en performance desktop, 81 en mobile, 86 en accessibilité et 100 en SEO. Ce n’était pas une épave négligée : hébergement correct, cache serveur, images optimisées, thème entretenu. Le genre de WordPress que je livre à mes clients et que je défends encore aujourd’hui.

Rapport PageSpeed Insights mobile de one-day.fr sous WordPress : performance 81, FCP 2,7 s, LCP 3,7 s, TBT 60 ms, Speed Index 5,6 s

Rapport PageSpeed Insights desktop de one-day.fr sous WordPress : performance 87, FCP 0,7 s, LCP 0,7 s, TBT 210 ms, Speed Index 2,7 s

Et pourtant, il plafonnait. Les rapports le disaient sans ambiguïté : TBT (Total Blocking Time) à 210 ms sur desktop, LCP mobile à 3,7 s, Speed Index mobile à 5,6 s, 178 Kio de JavaScript inutilisé, et un budget de requêtes bloquant le rendu estimé à 1 740 ms sur mobile. Aucune de ces valeurs n’est le signe d’un travail bâclé. C’est le coût structurel d’un thème et d’une pile de plugins : chacun injecte son CSS et son JavaScript, et même parfaitement réglé, l’ensemble reste lourd. On peut optimiser un WordPress pendant des jours ; on ne le fait pas descendre en dessous du plancher que son architecture impose.

Une curiosité au passage, que je signale sans la surinterpréter : le TBT était plus élevé sur desktop (210 ms) que sur mobile (60 ms). Contre-intuitif, puisqu’un téléphone d’entrée de gamme est censé souffrir davantage. L’explication la plus plausible tient au profil de test de Lighthouse : sur mobile, il simule une connexion 4G lente qui étale l’arrivée des scripts tiers dans le temps, si bien que les longues tâches se répartissent au lieu de se concentrer dans la fenêtre de mesure entre le premier affichage et l’interactivité. Sur desktop, réseau rapide, tout ce JavaScript arrive d’un coup et bloque le fil principal en bloc. Je le présente comme un constat mesuré, pas comme une vérité définitive — c’est le genre d’artefact de mesure qu’il faut savoir lire sans en tirer une théorie générale.

Ce qu’une migration de 15 ans implique vraiment

C’est la partie que les benchmarks jouets ne montrent jamais, parce qu’ils n’ont rien à trier. Migrer quinze ans de contenu n’est pas un lift-and-shift — copier le contenu tel quel d’un moteur à l’autre. C’est une décision éditoriale, prise sur des données.

Le pipeline, concrètement :

  • Export WXR natif de WordPress, puis un script Node maison (turndown pour convertir le HTML en Markdown, génération du frontmatter, rapatriement des images, production d’un inventory.csv de tout le contenu).
  • Croisement avec 16 mois de données Search Console (traitées sous pandas), page par page. Ce n’est pas le contenu qui décide de son sort, ce sont ses performances réelles en recherche.

Le tri qui en sort, sans fard : 15 pages « star » (3 818 clics cumulés), 44 pages conservées telles quelles, 16 à réécrire (bloquées en positions 50 à 77, du potentiel gâché par un contenu daté), une vingtaine élaguées en redirections 301, et une seule passée en 410 — supprimée pour de bon, assumée comme morte.

Le constat le plus intéressant est stratégique. 81 % du trafic venait d’articles techniques hors-marque — des tutoriels sur InDesign, sur le CSS, écrits au fil des années et qui n’ont rien à voir avec le cœur de métier actuel. La tentation « cohérence de marque » aurait été de les sacrifier. Décision inverse : les garder comme ancres d’autorité dans le hub /blog. On ne jette pas ce qui a construit l’autorité d’un domaine sur quinze ans au nom d’un branding propre. C’est une leçon qui dépasse ce site : le trafic qui ne « colle » pas à votre positionnement actuel est quand même le trafic qui fait exister votre domaine aux yeux de Google.

Le reste relève de l’hygiène de migration : conservation à l’identique des slugs (via une route catch-all qui sert chaque ancienne URL à sa place), une carte de redirections 301 pour ce qui bouge, et une bascule DNS vers Cloudflare — une ligne à changer, le détail de la sortie d’hébergement mériterait un article à lui seul.

Combien de temps, honnêtement ? De l’ordre d’une semaine de travail. Pas une après-midi — quiconque vous vend une migration de cette ampleur en une après-midi n’a pas fait le tri. Mais pas un trimestre non plus : l’essentiel du coût est dans l’analyse et les arbitrages, pas dans la technique.

Le résultat brut

Même URL, même outil, mêmes conditions. Le avant est mesuré le 17/07 à 16 h 04 sur le WordPress encore en ligne, le après le 18/07 à 07 h 47 sur le build Astro. Les valeurs sont reprises telles quelles des rapports, sans arrondi :

MétriqueWP desktopAstro desktopWP mobileAstro mobile
Performance8710081100
FCP0,7 s0,3 s2,7 s1,1 s
LCP0,7 s0,4 s3,7 s1,5 s
TBT210 ms0 ms60 ms0 ms
CLS0.00200.0040
Speed Index2,7 s0,4 s5,6 s1,1 s
Accessibilité8610086100
Bonnes pratiques10010096100
Navigation agentique1/33/31/33/3

Rapport PageSpeed Insights mobile de one-day.fr sous Astro : performance 100, FCP 1,1 s, LCP 1,5 s, TBT 0 ms, CLS 0, Speed Index 1,1 s

Rapport PageSpeed Insights desktop de one-day.fr sous Astro : performance 100, FCP 0,3 s, LCP 0,4 s, TBT 0 ms, toutes les métriques dans le vert

Deux choses à en retenir. D’abord, l’histoire est mobile. Le desktop était déjà correct — passer de 87 à 100 est agréable mais anecdotique. C’est sur mobile que tout se joue : LCP divisé par près de 2,5 (3,7 s → 1,5 s), Speed Index divisé par 5 (5,6 s → 1,1 s). C’est là que vivent vos vrais visiteurs, sur un téléphone milieu de gamme en réseau imparfait.

Ensuite, le TBT à 0 ms est la signature du modèle Astro, et il mérite qu’on le comprenne. Ce n’est pas du JavaScript brillamment optimisé : c’est du JavaScript qui n’existe pas. Astro génère la page à l’avance et n’envoie aucun script par défaut. On n’optimise pas ce qu’on n’expédie jamais.

Ce que le 100/100 cache

Voici la section que j’aurais aimé lire ailleurs, et que je ne trouve jamais. Un score parfait déclenche l’auto-satisfaction ; il devrait déclencher trois lucidités.

1. Le score plafonne avant la fin du travail. Le rapport Astro affiche 100, et pointe pourtant encore des économies possibles : des requêtes bloquant le rendu (environ 220 ms sur desktop, 570 ms sur mobile d’économies estimées) et un ajustement forcé de mise en page. Autrement dit, il reste du travail que Lighthouse ne pénalise plus. 100 ne veut pas dire « terminé ». 100 veut dire « au-delà du seuil où l’outil arrête de compter les points ». Ce sont deux choses très différentes, et confondre les deux, c’est arrêter d’optimiser au moment précis où l’outil cesse de vous applaudir.

2. Ce sont des données de laboratoire, pas de terrain. Les deux rapports affichent « aucune donnée » côté CrUX (le Chrome User Experience Report) : le site n’a pas assez de trafic pour alimenter les field data, les mesures issues des vrais navigateurs. Tout ce que vous lisez dans le tableau ci-dessus est une simulation — un device émulé, une connexion émulée. Les vrais utilisateurs, leurs vrais téléphones, leurs vraies connexions bancales ne sont pas dans ces chiffres. Le lab est un excellent indicateur ; ce n’est pas une preuve d’expérience réelle.

3. Ce n’est pas un comparatif à périmètre identique — et je l’assume. Entre le avant et le après, il n’y a pas eu qu’un changement de moteur. Il y a eu un triage, des réécritures, un élagage. Une partie du gain vient du régime, pas seulement de la nouvelle mécanique. Un lift-and-shift pur — le même contenu, bloc pour bloc, versé de WordPress vers Astro — aurait gagné moins que ça. Le dire ne fragilise pas la démonstration : ça la rend crédible. Astro apporte un plancher de performance très bas ; le tri éditorial apporte le reste. Les deux comptent, et prétendre que tout le mérite revient à la stack serait malhonnête.

Douze jours plus tard : ce qu’il a fallu faire après le 100

Cette section n’était pas prévue. Elle existe parce que j’ai voulu vérifier la première des trois lucidités ci-dessus — « le score plafonne avant la fin du travail » — au lieu de me contenter de l’écrire.

Le 30 juillet, douze jours après le rapport gelé plus haut, j’ai relancé la mesure. LCP mobile à 2,7 s, performance à 96. Plus haut que les 1,5 s du tableau. Je ne sais pas trancher entre les pages ajoutées depuis et la variance du nœud de test de Google, et je préfère le dire que d’inventer une explication. Ce qui importe est ailleurs : le rapport montrait un TTFB à 0 ms et un délai d’affichage de l’élément de 1 310 ms. Tout le retard était dans le rendu, rien dans le réseau. Et l’élément LCP était un texte — l’accroche du hero.

Ce qui a suivi est instructif surtout par ses erreurs.

La correction évidente n’a rien gagné. Trois feuilles de style bloquaient le rendu, dont une dont l’unique fonction était de déclarer des polices. Je les ai fait disparaître du chemin critique : quatre requêtes ramenées à une, à volume d’octets constant. Résultat sur le LCP : rien. Le délai d’affichage est passé de 1 310 à 1 320 ms. La cause était ailleurs, et j’avais corrigé le symptôme le plus visible.

La deuxième hypothèse était fausse aussi, et l’outil le disait déjà. Un LCP texte qui tarde, le réflexe est d’accuser la police : le navigateur masquerait le texte en attendant de la charger. Sauf que les dix-huit déclarations de police du site étaient déjà en font-display: swap, ce qui interdit précisément ce masquage — et l’audit font-display de Lighthouse passait au vert depuis le début. J’ai perdu deux passes à chercher un problème que l’outil avait déjà écarté à ma place. Lire les audits qui passent est aussi utile que lire ceux qui échouent.

La vraie cause était bête et invisible dans le score. Quatre fichiers de police partaient au démarrage sans être préchargés — 147 ko qui se disputaient la bande passante avec les deux polices du hero, elles préchargées. Le texte peignait bien tout de suite en police de repli, mais sa peinture définitive attendait la fin de cet embouteillage. Vérifié par une expérience de contrôle avant d’écrire une ligne : en ne laissant que les polices préchargées, le LCP tombait immédiatement.

Le reste n’est que du ménage, et c’est là que j’ai trouvé les choses gênantes. Une graisse de police était téléchargée sans que personne la demande : les libellés en mono n’avaient pas de graisse déclarée, héritaient la normale, et le navigateur allait chercher la voisine la plus proche — 32 ko pour rien. La marque du logo réclamait à elle seule une graisse de 35 ko qu’aucun autre élément n’utilisait. Et les fichiers de police transportaient des ligatures et des variantes dont le site ne se sert pas : Inter-400-latin annonçait 230 caractères et en embarquait 518. Sous-ensemblés sur la plage qu’ils déclarent déjà — sans retirer un seul caractère de couverture — les polices du chemin critique sont passées de 163 à 111 ko. Enfin l’en-tête servait l’icône PWA, 11,4 ko et 192 pixels de côté, pour un logo affiché en 28 : remplacée par un fichier dédié de 556 octets.

Le plus révélateur pour le propos de cet article n’est pourtant pas le LCP. C’est le CLS. Le rapport du 18 juillet affichait 0 sur les deux plateformes. Mon propre banc de mesure, lui, relevait 0,178 de décalage sur desktop — causé par un <strong> de l’accroche qui, en recevant sa graisse en retard, refaisait circuler le paragraphe. Je ne sais pas lequel des deux instruments décrit le mieux l’expérience d’un visiteur réel. Mais le décalage existait, il avait une cause identifiable, et le score parfait ne l’avait jamais signalé.

Bilan : quatre passes, dont une inutile et deux fondées sur une hypothèse fausse, pour aller d’un 100 déjà acquis à un 100 mobile et 100 desktop sur un site notablement plus léger — polices comprises, 713 ko de fichiers de police ramenés à 592. Aucune de ces optimisations n’a fait monter le score, puisqu’il était déjà au plafond. C’est bien le sujet de la section précédente : l’outil avait cessé de compter les points longtemps avant que le travail soit fini.

Les rapports d’arrivée, mesurés le 30 juillet à 11 h 25 :

Rapport PageSpeed Insights mobile de one-day.fr après optimisation : performance, accessibilité, bonnes pratiques et SEO à 100, navigation agentique 3/3, FCP 0,8 s, LCP 1,4 s, TBT 0 ms, CLS 0

Rapport PageSpeed Insights desktop de one-day.fr après optimisation : quatre scores à 100, navigation agentique 3/3, FCP 0,2 s, LCP 0,4 s, TBT 0 ms, CLS 0,012

Deux détails de ces rapports valent plus que les pastilles vertes. Le LCP mobile est à 1,4 s, contre 1,5 s au rapport de lancement : le site est bien plus rapide qu’au premier jour, pas seulement revenu à son niveau. Et le CLS desktop affiche 0,012 là où le rapport du 18 juillet donnait 0 — un décalage minuscule, largement dans le vert, que je n’arrive pas à reproduire sur mon banc de mesure et dont je ne connais donc pas la cause. Je le note plutôt que de l’ignorer : c’est exactement le genre de résidu qu’un score plein rend invisible.

Ce que Lighthouse ne mesurera jamais — et la suite

Le vrai verdict d’une migration ne s’affiche pas dans un rapport de performance. Il s’affiche dans Search Console, des mois plus tard : les positions ont-elles tenu ? Le trafic a-t-il suivi ? Les clics sont-ils au rendez-vous après la bascule des URL ? La latence de réindexation se compte en semaines et en mois, pas en secondes de chargement. À ce jour, rien de mesurable — et quiconque prétend le contraire moins d’une semaine après une migration invente.

C’est pourquoi ce récit est volontairement à moitié écrit. Un avant complet est gelé : rapports Lighthouse datés, 16 mois de données GSC archivées, positions figées. L’après SEO — celui qui juge vraiment l’opération — sera publié à l’automne, quand les index auront parlé. C’est le seul juge qui compte, et il prend son temps.

Reste une dimension nouvelle, glissée dans le tableau : la navigation agentique est passée de 1/3 à 3/3. Un site Astro, servi en HTML propre, se laisse lire par les agents IA bien mieux qu’un WordPress alourdi de scripts. Cet angle — comment cette migration a été pensée pour être lisible par les agents IA — est traité en détail dans un dossier dédié. Je m’arrête là ici : c’est un sujet à part entière, et le développer davantage sur cette page ferait doublon avec ce dossier.


Si vous envisagez une refonte, la question n’est pas « faut-il quitter WordPress ». C’est : qu’est-ce qui vous plafonne, et est-ce réparable sans changer de moteur ? Parfois oui — et je continue de livrer et d’entretenir des WordPress pour de bonnes raisons. Parfois le plafond est structurel, et aucun plugin d’optimisation ne le percera. Ce site était dans le second cas. Le savoir avant de commencer, ça vaut plus que vingt points de Lighthouse.