Le catalogue en question, celui d’un distributeur de quincaillerie professionnelle, comptait plus de 20 000 références actives, réparties sur des pages de catégorie affichant parfois plus de 200 produits avec filtres, tri et pagination, le tout piloté par WooCommerce en headless via sa Store API. Sur l’ancien front React classique, la page de catégorie la plus chargée affichait un temps avant interactivité (TTI) mesuré à plus de 4 secondes sur un mobile d’entrée de gamme, un chiffre jugé inacceptable par l’équipe marketing du distributeur.
Qwik, avec sa promesse de résumabilité plutôt que d’hydratation, a été identifié comme candidat à un test grandeur nature sur cette page précise, avant d’envisager une migration plus large du reste du site.
Hydratation classique contre résumabilité : la différence concrète
Sur un framework classique comme React ou Vue, même avec du rendu serveur, le navigateur doit télécharger l’intégralité du JavaScript de la page, l’exécuter, reconstruire l’arbre des composants en mémoire, puis attacher les gestionnaires d’événements sur chaque élément interactif, une étape appelée hydratation. Sur une page de catégorie avec 200 cartes produits, chacune avec son propre bouton d’ajout au panier et son propre sélecteur de variante, cette étape représente un volume de travail non négligeable pour le processeur du visiteur, en particulier sur mobile.
Qwik adopte une approche différente : le HTML envoyé au navigateur contient déjà, sous forme sérialisée, l’état nécessaire à chaque composant, et le code JavaScript associé à un gestionnaire d’événement précis n’est téléchargé qu’au moment où le visiteur interagit réellement avec cet élément, jamais avant. Le framework « reprend » l’exécution là où le serveur l’avait laissée, plutôt que de la rejouer entièrement depuis zéro.
Le protocole de test
La page de catégorie la plus lourde du catalogue a été reconstruite en Qwik, connectée à la même Store API WooCommerce que la version React existante, avec un rendu des mêmes 200 produits et les mêmes filtres. Les deux versions ont été mesurées avec Lighthouse en mode mobile simulé (CPU ralenti 4x), sur la même infrastructure d’hébergement, avec cinq mesures consécutives pour chaque version.

| Métrique | Version React (hydratation) | Version Qwik (résumabilité) |
|---|---|---|
| Temps avant interactivité (TTI) | 4,1 s | 1,3 s |
| JavaScript exécuté au chargement | 340 Ko | 28 Ko |
| Total Blocking Time | 890 ms | 95 ms |
Le gain mesuré sur le TTI atteint 68 % sur cette page précise, un écart nettement supérieur à ce que l’équipe anticipait avant le test. La différence s’explique surtout par le volume de JavaScript exécuté immédiatement au chargement : la version React devait initialiser les 200 composants de carte produit d’un coup, tandis que la version Qwik ne charge le code interactif d’un bouton d’ajout au panier qu’au moment où le visiteur le touche réellement.
Ce qui a posé problème pendant le test
La compatibilité des bibliothèques tierces
Le sélecteur de variante produit s’appuyait, côté React, sur une bibliothèque de composants d’interface tierce très répandue, sans équivalent direct dans l’écosystème Qwik encore jeune à cette période. Il a fallu réécrire ce composant depuis zéro en respectant les conventions de résumabilité de Qwik, notamment l’usage de $() pour marquer les fonctions destinées à être chargées paresseusement :
export const SelecteurVariante = component$((props) => {
const variante = useSignal(props.varianteParDefaut);
return (
<select
value={variante.value}
onChange$={(e) => {
variante.value = e.target.value;
}}
>
{props.variantes.map((v) => (
<option key={v.id} value={v.id}>{v.nom}</option>
))}
</select>
);
});
La courbe d’apprentissage de l’équipe
Les développeurs du projet, expérimentés en React depuis plusieurs années, ont sous-estimé le temps d’adaptation nécessaire aux concepts propres à Qwik : les signaux réactifs, la sérialisation explicite de l’état, et surtout le raisonnement à adopter pour découper le code de façon à maximiser les bénéfices du chargement paresseux. Le prototype de la page catégorie a demandé environ deux semaines de plus que prévu initialement, un délai attribué directement à cette phase d’apprentissage.
La décision finale
- La migration complète du site vers Qwik n’a pas été retenue à ce stade, jugée trop coûteuse en réécriture face à un écosystème de composants tiers encore limité par rapport à React.
- La page de catégorie et la page produit, les deux gabarits les plus consultés et les plus lourds du catalogue, ont en revanche été migrées vers Qwik en production, avec un pont de navigation vers le reste du site resté en React.
- Cette approche hybride, bien que techniquement plus complexe à maintenir (deux frameworks cohabitant), a été jugée le meilleur compromis entre gain de performance mesurable et effort de réécriture supportable par l’équipe.
Un gain de performance mesuré sur un prototype ne justifie pas automatiquement une migration totale ; il justifie de migrer en priorité les pages où ce gain a le plus de valeur réelle pour le visiteur.
En résumé
La résumabilité de Qwik a tenu ses promesses sur ce cas précis, avec un gain de performance largement supérieur à ce qu’une simple optimisation du code React existant aurait permis d’obtenir. Le prix à payer reste réel : un écosystème de composants moins mature, une courbe d’apprentissage sous-estimée, et une cohabitation de deux frameworks qui alourdit la maintenance. La bonne question n’est donc pas « Qwik est-il meilleur que React », mais « où, précisément dans le site, ce gain justifie-t-il cet effort ».