Veille Tech

Installer un site Drupal en 90 secondes au lieu de 20 minutes : profiler PHP et agent IA à la rescousse

Sur un gros projet Drupal multilingue, chaque installation du site prenait près de 20 minutes, rendant les pipelines de CI interminables. En combinant un profiler PHP léger (SPX) et un agent de codage IA connecté aux données de profilage, l'équipe de Nuvole a ramené ce temps à 90 secondes. Décryptage d'une méthode reproductible, avec des enseignements directs pour les délais, les coûts de CI et la vélocité des équipes.

Le point de départ : une installation si lente qu'elle décourage les tests

Le projet décrit par Alex Davyskiba (Nuvole) est un site Drupal de grande envergure : contenus en 100 langues, environ 200 modules, plus de 400 champs configurés et jusqu'à 5 000 fichiers de configuration en comptant les traductions. Sur cette base, la commande drush site:install (l'installation complète du site pilotée par la configuration) prenait près de 20 minutes. En ajoutant le démarrage des conteneurs Docker et l'exécution des tests de bout en bout, un seul passage de CI (intégration continue, l'exécution automatique des tests à chaque modification du code) pouvait durer une heure.

Copier la base de production dans la CI n'étant pas envisageable, l'installation complète à partir de la configuration restait le seul moyen d'obtenir un site propre à tester pour chaque changement. Or une installation aussi lente ne coûte pas seulement des minutes de CI : elle allonge chaque boucle de feedback et incite les équipes à contourner les tests. D'où l'objectif : comprendre précisément où partaient ces 20 minutes, corriger ce qui pouvait l'être, et voir dans quelle mesure l'IA pouvait raccourcir le cycle mesurer-corriger-remesurer.

Étape 1 : installer un profiler pour voir ce que fait réellement Drupal

La première étape a consisté à instrumenter l'installation avec SPX, un profiler PHP léger (un outil qui mesure le temps et la mémoire consommés par chaque fonction du code). SPX s'intègre facilement dans une image PHP sous Docker, avec un surcoût de performance bien moindre que des alternatives comme Xdebug ou Blackfire.

Une fois activé, SPX fournit une interface web pour parcourir les profils enregistrés : temps d'exécution, mémoire et nombre d'appels par fonction, ainsi qu'une vue en « flame graph » (représentation graphique de la pile d'appels qui met en évidence les fonctions les plus coûteuses) accompagnée d'un tableau triable des fonctions les plus gourmandes.

Étape 2 : donner à un agent IA l'accès direct aux profils

SPX dispose d'une extension MCP (Model Context Protocol, un protocole qui permet à un agent IA d'interroger des outils externes) : SPX-MCP expose les profils enregistrés via une interface de requêtage, sans passer par le navigateur. Connecté à cette source de données, l'agent de codage peut lister les profils, explorer une requête précise et extraire les fonctions responsables du temps passé, sans qu'un humain doive d'abord ouvrir et interpréter un flame graph.

Concrètement, un prompt de deux lignes a suffi pour que l'agent retrouve les profils les plus récents, remarque de lui-même qu'il s'agissait de requêtes de pages classiques et non de l'installation visée, puis, une fois orienté vers le bon rapport, décompose une requête de page d'accueil de 1,44 seconde en rendu HTML, compilation Twig, chargement de classes, lectures de cache et temps base de données, avec les noms de fonctions concernés. C'est exactement le triage qu'un développeur ferait à la main, mais obtenu beaucoup plus vite.

Étape 3 : découper un profil ingérable en profils par tâche d'installation

Profiler une page est simple ; profiler une installation de 20 minutes l'est beaucoup moins. Activer SPX sur l'ensemble du processus a produit un profil unique de près de 590 millions d'appels, pesant environ 8 Go : trop volumineux pour l'interface web, et trop gros pour qu'un agent IA puisse raisonner dessus d'un bloc.

La solution : découper le profilage par étape d'installation. L'installeur de Drupal enchaîne une séquence fixe de tâches (install_select_language, install_config_import_batch, install_import_translations, etc.), toutes orchestrées par une seule fonction du cœur, install_run_tasks(). Un petit patch à cet endroit démarre et arrête un profil SPX autour de chaque tâche, en l'étiquetant avec le nom de la tâche en métadonnée. Résultat : un profil ingérable transformé en une douzaine de petits profils, chacun limité à une tâche et assez léger pour être chargé et interrogé par l'agent comme par un humain. Pour les rares profils restant trop volumineux, l'outil en ligne de commande SPXQ permet de parcourir des rapports SPX de plusieurs gigaoctets sans tout charger en mémoire.

Étape 4 : la boucle profiler-corriger-reprofiler, pilotée par l'agent

Avec des profils par tâche, le travail devient une boucle : profiler une tâche, identifier la fonction la plus coûteuse, la corriger, relancer l'installation, vérifier le gain dans le nouveau profil. Fait à la main, tâche par tâche, ce travail est fastidieux — c'est précisément le type de travail répétitif et bien délimité pour lequel un agent IA excelle, dès lors qu'il accède directement aux données de profilage.

Exemple parlant : la tâche install_config_import_batch passait l'essentiel de son temps dans EntityStorageBase::doPostSave(). L'analyse de la chaîne d'appels a montré que la sauvegarde d'une seule configuration de champ redéclenchait des hooks et des invalidations de cache pour les définitions de champs de base de tous les types d'entités, alors qu'un seul bundle avait changé — et cela pour chacune des centaines de configurations de champs. Après chaque correctif, l'agent relançait l'installation, récupérait le nouveau profil et confirmait l'amélioration par rapport au passage précédent.

Les optimisations qui ont réellement fait la différence

Après plusieurs tours de cette boucle, voici les correctifs qui ont le plus pesé :

  • Mettre en cache les noms de collections de configuration : StorageComparer::getAllCollectionNames() rescannait le répertoire de synchronisation pour chacun des ~2 800 éléments de configuration importés, alors que la réponse ne change jamais. Le calculer une fois par import a réduit cette étape de 27,6 %.
  • Mettre en cache la configuration par défaut traduisible : LocaleConfigManager::getTranslatableDefaultConfig() reconstruisait un wrapper de configuration typée pour chaque langue, alors que la configuration par défaut est identique d'une langue à l'autre. Un cache par nom de configuration a réduit ce poste de 53,5 %.
  • Mettre en cache isSupported() : deux lectures de configuration redondantes par langue pour une réponse indépendante de la langue ; le cache a retiré encore 5,4 %.
  • Scanner le répertoire de traductions une seule fois : le même dossier, généralement vide, était scanné pour chaque couple projet/langue, jusqu'à 1 580 fois. Le lister une fois et comparer les noms de fichiers à cette liste a ramené l'étape à environ 6 millisecondes.
  • Supprimer les sauvegardes de configuration inutiles : LocaleConfigManager::updateConfigTranslations() sauvegardait des configurations même quand rien n'avait été traduit, rechargeant au passage les objets de surcharge linguistique pour toutes les langues. Une simple garde !empty($processed) a éliminé 237 sauvegardes superflues.
  • Ne plus forcer la reconstruction d'une carte de champs encore froide : après chaque reconstruction du conteneur, FieldDefinitionListener::onFieldDefinitionCreate() forçait une reconstruction complète de la carte des champs pour chaque champ créé pendant l'installation. Sauter cette étape tant que la carte est froide a réduit de 76 % les appels à getBaseFieldDefinitions(), sans aucun changement sur le résultat final.
  • Restreindre le vidage de cache à la sauvegarde d'un champ : le gain le plus important. Sauvegarder une configuration de champ effaçait les définitions de champs de base de tous les types d'entités et déclenchait une redécouverte complète des plugins. Ne vider que les définitions du bundle concerné pendant l'installation a réduit cette étape de 18 %, avec des définitions vérifiées identiques à l'octet près sur 37 combinaisons entité/bundle.
  • Neutraliser le stockage du statut de traduction pendant l'installation : un petit wrapper transforme les consultations de locale.translation_status en opération mémoire sans effet pendant l'installation, puis redevient transparent ensuite.

Ce que cette méthode change pour un projet Drupal

Au-delà des correctifs eux-mêmes, c'est la méthode qui est transposable : instrumenter avec un profiler léger, découper la mesure en unités exploitables, puis confier à un agent IA la boucle répétitive d'analyse et de vérification. Le passage de 20 minutes à 90 secondes d'installation se traduit directement en pipelines de CI plus courts, en coûts d'infrastructure réduits et surtout en boucles de feedback assez rapides pour que les tests restent une habitude plutôt qu'une corvée. Sur un projet complexe, c'est la vélocité de toute l'équipe qui en bénéficie.

Avis Tuesday

Ce retour d'expérience valide une méthode que nous jugeons directement applicable aux projets Drupal complexes que nous accompagnons en TMA : mesurer avant d'optimiser, découper le problème en unités exploitables, puis déléguer à un agent IA la boucle répétitive d'analyse et de vérification — l'humain gardant la main sur les correctifs et leur validation. Attention toutefois : plusieurs optimisations décrites patchent le cœur de Drupal et doivent être soigneusement isolées au contexte d'installation pour ne pas introduire de régressions en production. Si vous voulez voir comment ce type de démarche performance se traduit concrètement sur un projet, nos études de cas Drupal (Onduline, Eqiom, Esset) illustrent cette approche dans la durée.

Pour aller plus loin · Nos expertises

Ce signal touche plusieurs de nos expertises.

Expertise Drupal Performance, sécurité & DevOps Intégration IA & automatisation
Julie D.
Responsable veille Julie D.

Responsable de la veille digitale chez Agence Tuesday. Décrypte les tendances tech, IA et marketing pour en tirer des enseignements concrets.

Découvrir l'équipe Tuesday

Newsletter · 1 envoi / semaine

Tout le savoir Tuesday,
dans votre boîte mail

Articles de fond et veille de la semaine, sélectionnés et commentés. Un seul abonnement pour les deux flux. Pas de spam, jamais — ~2 200 abonnés.

En vous abonnant, vous acceptez de recevoir la newsletter de l'agence Tuesday. Désinscription en un clic.