# Le piège de l’autoload de wp_options qui ralentit chaque page WordPress

> Comment un autoload de wp_options mal maîtrisé finit par ralentir chaque requête WordPress, et comment le diagnostiquer puis le corriger sans risque.

- Auteur : Clément Hadrot
- Publié le : 2021-04-22
- Mis à jour le : 2021-04-22
- Catégorie : Performance
- URL : https://wpmoderne.dev.wordpress-developpement.fr/performance/autoload-wp-options-piege-performance/

## L’essentiel

- L'autoload charge certaines options à chaque page, même quand elles sont inutiles
- Un plugin mal codé peut y stocker des mégaoctets de données inutiles
- WP-CLI permet de diagnostiquer et corriger le problème en quelques commandes

Il y a des ralentissements WordPress spectaculaires, faciles à repérer : une requête SQL absente d'index, une extension qui appelle une API externe de façon synchrone. Et il y a les ralentissements sournois, ceux qui touchent absolument toutes les pages du site sans exception, sans qu'aucun profileur ne pointe vers un coupable évident. L'autoload de la table `wp_options` appartient à cette deuxième catégorie, et c'est probablement l'un des pièges de performance les plus sous-estimés de l'écosystème WordPress.

Le principe de l'autoload est pourtant une bonne idée à l'origine : plutôt que d'interroger la base de données à chaque fois qu'une option est nécessaire, WordPress charge en une seule requête toutes les options marquées `autoload = yes`, dès le tout début de son exécution, et les garde en mémoire pour le reste de la requête. Le problème survient quand cette liste d'options « à charger systématiquement » grossit sans contrôle, au fil des extensions installées et jamais vraiment désinstallées proprement.

## Comment l'autoload grossit sans qu'on s'en aperçoive

Chaque fois qu'une extension appelle `add_option()` sans préciser explicitement le troisième paramètre, l'option est enregistrée avec `autoload` à `yes` par défaut. C'est également le cas de nombreux appels à `update_option()` sur des options qui n'existaient pas encore. Certaines extensions y stockent des réglages légitimes de quelques kilo-octets ; d'autres, moins soigneusement codées, y stockent des caches applicatifs entiers, des journaux d'événements, ou des résultats d'API externes qui n'ont strictement rien à faire dans une option chargée à chaque page.

Les *transients* sont une source de dérive fréquente. Sur un site sans cache d'objets persistant (voir notre article sur Redis), WordPress stocke les transients directement dans `wp_options`, avec un nom préfixé `_transient_` et une donnée d'expiration séparée. Si un développeur crée un transient avec `set_transient()` sans se soucier de l'autoload, ou si un plugin génère des centaines de transients avec des clés dynamiques jamais nettoyées, la table gonfle discrètement, mois après mois.

## Le symptôme : un ralentissement diffus sur tout le site

Le problème avec un autoload trop lourd, c'est qu'il ne se manifeste pas par une erreur, ni même par une lenteur localisée à une page précise. Chaque chargement de WordPress, qu'il s'agisse de l'accueil, d'un article, d'une requête AJAX ou même d'une commande WP-CLI, exécute cette même requête d'initialisation qui charge toutes les options autoloadées en mémoire. Plus cette liste est volumineuse, plus cette étape, pourtant invisible dans la plupart des outils de mesure applicatifs, ralentit systématiquement chaque exécution.

- Un cache de page comme fastcgi_cache masque le problème pour les visiteurs anonymes, mais ne le résout pas : les requêtes non mises en cache (panier, recherche, admin) restent pénalisées.
- Un cache d'objets comme Redis atténue l'impact sur les requêtes SQL répétées, mais la première charge à chaque redémarrage du cache reste coûteuse.
- Le tableau de bord d'administration, qui échappe à la plupart des caches, devient souvent le premier endroit où la lenteur se fait sentir concrètement.

> L'essentiel à retenir : L'autoload charge certaines options à chaque page, même quand elles sont inutiles ; Un plugin mal codé peut y stocker des mégaoctets de données inutiles ; WP-CLI permet de diagnostiquer et corriger le problème en quelques commandes

## Diagnostiquer la taille de l'autoload

La requête SQL suivante donne un premier diagnostic rapide, en se connectant directement à la base de données ou via `wp db query` :

```
SELECT SUM(LENGTH(option_value)) / 1024 / 1024 AS taille_mo,
       COUNT(*) AS nb_options
FROM wp_options
WHERE autoload = 'yes';
```

En usage courant, un site WordPress raisonnablement équipé se situe sous 1 Mo d'autoload. Au-delà de 2 ou 3 Mo, il est temps d'investiguer. Nous avons déjà constaté des cas dépassant 10 Mo sur des sites e-commerce accumulant années de transients et de journaux d'extensions jamais purgés.

Pour identifier précisément les options les plus lourdes, cette variante trie les coupables :

```
SELECT option_name, LENGTH(option_value) / 1024 AS taille_ko
FROM wp_options
WHERE autoload = 'yes'
ORDER BY LENGTH(option_value) DESC
LIMIT 20;
```

## Utiliser WP-CLI pour aller plus vite

WP-CLI simplifie grandement ce diagnostic, sans avoir à ouvrir un client SQL. La commande `wp option list` accepte un filtre sur l'autoload :

```
wp option list --autoload=on --format=table --orderby=option_id
```

Pour repérer spécifiquement les transients expirés qui traînent encore dans la base :

```
wp transient list --format=table
wp transient delete-expired
```

La commande `wp transient delete-expired` supprime proprement les transients dont la date d'expiration est dépassée, y compris leur entrée d'expiration associée, ce qui est nettement plus sûr qu'une suppression manuelle par requête SQL directe.

## Corriger le problème sans casser le site

Une fois les options les plus lourdes identifiées, plusieurs actions sont possibles, à choisir selon le cas :

- Si l'option provient d'une extension encore active et légitimement volumineuse (un cache de résultats, par exemple), le plus sûr est de contacter l'auteur ou de vérifier s'il existe un réglage pour désactiver l'autoload sur cette donnée précise.
- Si l'option appartient à une extension désinstallée depuis longtemps, elle peut généralement être supprimée sans risque avec `wp option delete nom_de_loption`, après vérification qu'aucun code actif n'y fait encore référence.
- Pour une option que l'on contrôle soi-même dans du code personnalisé, il suffit de repasser son autoload à `no` lors de sa création ou de sa mise à jour, via le troisième paramètre de `add_option( $name, $value, '', 'no' )` ou en appelant `wp_set_option_autoload( $name, false )` sur les versions récentes de WordPress.

> Ne supprimez jamais une option de `wp_options` sans avoir vérifié son rôle au préalable. Certaines options au nom peu explicite (réglages de permaliens, clés de widgets actifs) sont critiques pour le fonctionnement du site. Faites toujours une sauvegarde de la base avant une purge, même ciblée.

## En résumé

L'autoload de `wp_options` est un exemple parfait de dette technique invisible : chaque extension installée y ajoute sa petite pierre, sans qu'aucune ne soit individuellement responsable du ralentissement global. C'est justement pour ça qu'il mérite une vérification périodique, au même titre qu'on surveille la taille de la base de données ou le nombre de révisions d'articles. Une requête SQL de trente secondes et quelques commandes WP-CLI suffisent à transformer un site qui traîne discrètement la patte en site qui répond enfin comme il le devrait.
