
Développement web · Astro et performances
Astro 7.4 révèle ce qui ralentit un build. Tutoriel, appels API, images, Node.js et prérendu parallèle expérimental.
Depuis le 15 octobre 2026, Astro 7.4 propose astro build --timings, un nouvel outil pour comprendre ce qui ralentit la génération d’un site web. Plugins Vite, Markdown, images, intégrations ou composants : plutôt que de chercher au hasard, les développeurs peuvent identifier les postes réellement coûteux et vérifier l’effet de leurs optimisations.
Cette nouveauté intéresse particulièrement les sites vitrines volumineux, catalogues B2B et plateformes éditoriales. Elle ne garantit pas à elle seule un build plus rapide : c’est un instrument de diagnostic, dont voici une utilisation concrète, ainsi que les limites des autres fonctions d’Astro 7.4.
La commande --timings permet de distinguer les temps des phases du build, le rendu des composants, les plugins Vite, le traitement Markdown, les transformations d’images et les hooks d’intégration. Le prérendu parallèle, également ajouté dans Astro 7.4, reste expérimental et doit être testé séparément.
Au fil des nouvelles pages et intégrations, un build peut prendre beaucoup plus de temps qu’au lancement d’un projet. Astro 7.4 affiche désormais, en fin de compilation, un rapport qui détaille les zones de consommation de temps. Pour commencer, vérifiez la version de Node.js et d’Astro puis relancez le build :
node --version
npx astro --version
npx astro build --timings
Le diagnostic répartit les coûts entre configuration, préparation, bundles client et serveur, génération des pages, plugins Vite, Markdown, coloration syntaxique, images et intégrations. Il met également en évidence des pages ou des fichiers plus lents que les autres. Ce rapport n’attribue pas nécessairement chaque milliseconde à une seule ligne de code, mais il détermine où enquêter.
| Section du rapport | Signal possible | Vérification recommandée |
|---|---|---|
| Generate pages / Component render | Rendu de pages ou composants trop coûteux | Appels API, layouts partagés, calculs répétitifs |
| Vite plugins / Bundles | Transformations ou plugins lourds | Comparer en isolant le plugin responsable |
| Markdown / Syntax highlighting | Traitement de contenus et blocs de code | Limiter les transformations inutiles |
| Images | Conversions et redimensionnements | Formats, dimensions et stratégies de cache |
| Integration hooks | Préparation ou traitements d’intégration | Inspecter les opérations déclenchées au build |
Une précaution : certaines tâches s’exécutent concurremment. La somme de toutes les durées affichées n’est pas nécessairement égale au temps total écoulé. Pour évaluer une accélération, comparez toujours le temps total et le détail de la phase ciblée.
Imaginons un catalogue B2B dont les 600 fiches produits sont construites à partir d’une API, avec descriptions, visuels et caractéristiques. Ce cas est une mise en situation pédagogique, pas un benchmark réalisé par SDX : les mesures de ce projet restent à collecter.
Si les « slowest pages » appartiennent majoritairement aux fiches produits et que « component render » domine, il faut examiner les composants et les requêtes de ces fiches. Si le coût principal apparaît dans « images », l’optimisation du pipeline visuel sera prioritaire. Le rapport permet précisément de ne pas confondre ces deux causes.
Pour démontrer la fonctionnalité, Astro a enrichi un blog de neuf pages avec une section de commentaires qui récupère d’abord les commentaires, puis les profils des auteurs. Les appels successifs rallongent la génération. Une fois ces requêtes regroupées avec Promise.all(), la phase de génération des pages passe de 2,10 à 1,13 seconde.
| Indicateur | Avant | Après |
|---|---|---|
| Phase « generate pages » | 2,10 s | 1,13 s |
| Organisation des appels | Requêtes en cascade | Requêtes regroupées |
| Périmètre | Exemple officiel Astro de neuf pages uniquement | |
Il ne s’agit ni du temps total de compilation après optimisation, ni d’un gain généralisable aux catalogues de 600 pages. Le build total initial de la démonstration affichait 2,61 secondes, mais le résultat mis en avant, 2,10 → 1,13 seconde, porte bien sur la génération des pages.
Dans un composant Astro, les données détaillées et les données de stock d’un produit peuvent être récupérées l’une après l’autre alors qu’elles ne dépendent pas l’une de l’autre :
---
const { product } = Astro.props;
const api = import.meta.env.CATALOG_API_URL;
const details = await fetch(api + "/products/" + product.id)
.then((r) => r.json());
const stock = await fetch(api + "/stock/" + product.id)
.then((r) => r.json());
---
On peut lancer ces deux appels ensemble avec Promise.all() :
---
const { product } = Astro.props;
const api = import.meta.env.CATALOG_API_URL;
async function getJson(path) {
const response = await fetch(api + path);
if (!response.ok) throw new Error("API " + response.status);
return response.json();
}
const [details, stock] = await Promise.all([
getJson("/products/" + product.id),
getJson("/stock/" + product.id),
]);
---
Cette approche peut diminuer l’attente, mais elle ne réduit pas le nombre d’appels. Elle nécessite une gestion des erreurs et un parallélisme compatibles avec les limites de l’API ; lancer des centaines de demandes simultanées peut au contraire saturer le service.
Si les produits sont disponibles dans une réponse commune, getStaticPaths() permet de préparer les routes statiques et de transmettre les données requises aux pages, sans interroger de nouveau l’API pour chaque propriété déjà connue :
---
// src/pages/catalogue/[slug].astro
export async function getStaticPaths() {
const api = import.meta.env.CATALOG_API_URL;
const response = await fetch(api + "/products");
if (!response.ok) throw new Error("Catalogue indisponible");
const products = await response.json();
return products.map((product) => ({
params: { slug: product.slug },
props: { product },
}));
}
const { product } = Astro.props;
---
<h2>{product.name}</h2>
<p>{product.description}</p>
Ce code est volontairement simplifié : il suppose que le contenu de l’API peut être chargé en bloc et qu’une fiche statique n’exige pas un rafraîchissement immédiat. Sur une vraie plateforme, on choisira une couche de données commune, un cache maîtrisé et, si nécessaire, une pagination ou des appels groupés. Le stock ou les prix très variables ne doivent pas être figés sans stratégie d’actualisation : ils peuvent nécessiter du rendu à la demande.
Les autres pistes suivent la même logique : éliminer les traitements Markdown redondants, examiner les plugins Vite, éviter les calculs répétés dans un layout et repérer les conversions d’images anormalement nombreuses. Chaque changement doit correspondre à une hypothèse vérifiable dans --timings.
Il est tentant de comparer une exécution locale avec un build effectué sur un autre ordinateur ou dans une CI. Pourtant, CPU, mémoire, état du cache, débit de l’API, versions de Node.js et contenu exact peuvent modifier les temps mesurés. La comparaison n’a de valeur qu’à périmètre constant.
--timings de plusieurs essais.Un protocole pratique consiste à effectuer cinq exécutions par variante, en distinguant bien builds à cache froid et builds à cache chaud. C’est une méthode proposée pour l’article, pas une valeur de référence officielle d’Astro.
| Tableau de relevé du catalogue | Avant | Après |
|---|---|---|
| Temps total médian | À mesurer | À mesurer |
| Phase « generate pages » | À mesurer | À mesurer |
| Transformations d’images | À mesurer | À mesurer |
| Mémoire maximale en CI | À mesurer | À mesurer |
| Nombre de pages produites | 600 attendues | 600 attendues |
Pourquoi ces cellules ne contiennent-elles aucun chiffre ? Parce qu’aucune compilation de ce catalogue fictif n’a été effectuée. Un article technique fiable doit distinguer le protocole proposé des résultats réellement obtenus.
Astro 7.4 introduit experimental.parallelPrerender, qui répartit le prérendu statique sur plusieurs worker threads Node.js. Ce mécanisme peut être pertinent sur des projets riches en calcul, avec plusieurs cœurs disponibles. Il s’active par exemple ainsi :
// astro.config.mjs — test uniquement
import { defineConfig } from "astro/config";
export default defineConfig({
experimental: {
parallelPrerender: { workers: 4 },
},
});
Par défaut, Astro utilise tous les cœurs disponibles sauf un lorsque l’option est activée sans nombre de workers explicite. Chaque worker peut générer plusieurs pages selon build.concurrency, mais il augmente aussi la consommation mémoire. Une machine disposant de peu de mémoire ou un build limité par des services réseau n’en tirera pas forcément avantage.
L’option est ignorée lorsque l’adaptateur possède son propre système de prérendu. Parmi les adaptateurs officiels, c’est notamment le cas de @astrojs/cloudflare, pour lequel Astro affiche un avertissement. Mesurez les temps, le nombre de cœurs réellement exploités et le pic mémoire avant de conserver le réglage.
Le bon ordre est donc : supprimer d’abord les appels API inutiles, vérifier les postes coûteux avec --timings, puis comparer les configurations de workers seulement lorsque le rendu CPU constitue un goulot d’étranglement démontré.
Astro 7.4 autorise un service pour les pages prérendues au build et un autre pour les pages rendues à la demande. On peut, par exemple, utiliser Sharp pendant la construction et un service CDN adapté au runtime de production :
// astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
image: {
service: {
build: { entrypoint: "astro/assets/services/sharp" },
runtime: { entrypoint: "my-image-cdn-service" },
},
},
});
Le nom my-image-cdn-service est un placeholder, et non un module prêt à l’emploi : il doit être remplacé par un service d’images compatible installé et configuré. Le service de build sert aussi pendant le développement ; le service runtime est destiné aux pages à la demande et à l’endpoint d’images en production. Le service unique traditionnel reste pris en charge.
Astro 7.4 et ses intégrations officielles exigent au minimum Node.js 22.22.0. Il faut donc vérifier à la fois les postes de développement, les images Docker, la CI et l’hébergement, puis tester les dépendances lors de la mise à jour. La commande de migration recommandée est :
npx @astrojs/upgrade
Les intégrations @astrojs/cloudflare et @astrojs/markdoc doivent également être actualisées vers leurs versions compatibles avec astro@^7.4.0. Pensez à sauvegarder le projet et à valider le résultat du build avant déploiement.
Parmi les changements annexes figurent le nouveau gestionnaire notFound() pour les points d’entrée construits avec astro/fetch ou astro/hono, une meilleure détection des paramètres de polices non pris en charge par leur fournisseur et une page de redirection statique personnalisée, expérimentale.
La performance de génération mesure la rapidité du travail effectué avant la mise en ligne : compilation, récupération des données, traitements et production des fichiers. Elle affecte surtout les équipes, l’intégration continue et les délais de déploiement.
La performance de chargement concerne l’expérience des visiteurs : temps réseau, JavaScript, polices, images, cache et réactivité. Les Core Web Vitals évaluent notamment le LCP (chargement), l’INP (interactions) et le CLS (stabilité visuelle). --timings ne mesure aucun de ces indicateurs.
Le SEO technique dépend aussi de l’indexabilité, des balises, de la structure HTML, des URL canoniques, du maillage et du sitemap. Un build plus rapide ne corrige pas automatiquement ces problèmes. Il faut mesurer les Core Web Vitals et contrôler séparément le contenu rendu et son accessibilité aux moteurs de recherche.
Si l’enjeu concerne surtout la taille des images livrées au navigateur, notre article sur JPEG XL, WebP et AVIF couvre un chantier complémentaire : le poids transféré aux utilisateurs n’est pas la même chose que le temps de traitement des images durant la génération.
--timings accélère le site ?Non. Le rapport identifie des lenteurs du build ; il faut encore corriger leur cause et mesurer l’effet réel des changements. Il n’agit pas directement sur l’expérience des visiteurs.
Observez les pages les plus lentes et la section de rendu des composants, puis inspectez les layouts communs, les requêtes, les boucles coûteuses et les traitements externes. Le rapport oriente l’enquête, sans indiquer à lui seul une ligne de code précise.
La fonctionnalité expérimentale est ignorée par @astrojs/cloudflare, dont le système gère déjà son propre prérendu. Il ne faut donc pas lui attribuer des gains inexistants.
L’outil de diagnostic vaut le test sur un build lent. Avant une migration durable, vérifiez la version minimale de Node.js, les intégrations et l’environnement de déploiement. L’option de timings peut être utilisée sans activer le prérendu parallèle.
La nouveauté la plus utile d’Astro 7.4 est la visibilité sur la chaîne de génération. Avec astro build --timings, on peut identifier un appel externe répétitif, un composant lent ou une transformation coûteuse, traiter cette cause et comparer le résultat. Le prérendu parallèle et les services d’images séparés répondent à d’autres besoins, mais ne remplacent pas cette démarche.
Chez SDX Development, cette logique s’applique à la conception, à la refonte et à l’optimisation des sites professionnels : livrer plus efficacement, conserver un socle maintenable et vérifier indépendamment la performance ressentie par les visiteurs.
--timings.Le tableau de mesures officielles concerne le projet de démonstration Astro, et non un catalogue réel. Le cas de 600 fiches constitue une méthode reproductible dont les résultats restent à mesurer.
DÉVELOPPEMENT WEB
Migration PHP, mise à jour de CMS ou évolution de framework : identifiez les points de compatibilité et validez les parcours essentiels avant la mise en ligne.
Saisissez au moins 2 caractères pour lancer la recherche.