Sur un site e-commerce que nous suivons, chaque page front chargeait près de 180 kilo-octets de données depuis la table wp_options, avant même que WordPress n’ait affiché le moindre contenu. En creusant, une seule extension de fidélité client représentait plus du tiers de ce poids : elle stockait l’historique complet des points de ses membres dans une option unique, chargée automatiquement à chaque visite.
Ce problème ne se voit pas dans un profileur classique, puisque la requête SQL qui charge l’autoload est unique et rapide en apparence. C’est son cumul, option après option, extension après extension, qui finit par peser lourd sur chaque affichage. La bonne nouvelle : la décision se prend option par option, et elle se mesure.
Ce que fait réellement l’autoload
Quand une extension appelle add_option( 'mon_extension_historique', $donnees ) sans préciser de troisième paramètre, WordPress positionne la colonne autoload à 'yes' par défaut. Concrètement, cela signifie que la fonction wp_load_alloptions() ira chercher cette valeur en une seule requête groupée, dès le tout premier appel à get_option() sur la requête en cours, qu’on en ait besoin ou non sur cette page précise.
Pour une petite option de configuration lue à chaque affichage, comme une clé d’API ou un réglage d’affichage, c’est exactement le comportement souhaité : une seule requête regroupée bat toujours plusieurs requêtes séparées. Le problème apparaît quand l’option grossit avec le temps, ou quand elle n’est utile que sur un sous-ensemble de pages précis, comme un écran d’administration ou un cron.
Identifier les options à corriger
La commande WP-CLI suivante liste les options par poids d’autoload décroissant, ce qui suffit en général à repérer le ou les coupables :
wp option list --autoload=on --format=table \
--fields=option_name,size_bytes \
--orderby=size_bytes --order=DESC | head -n 20
Sur le site cité en introduction, cette commande a immédiatement pointé fidelite_historique_points avec plus de 60 kilo-octets à elle seule, suivie d’un cache de traduction généré par une autre extension. Aucune des deux n’était consultée sur la majorité des pages du site.
Corriger sans casser le fonctionnement existant
Changer l’autoload d’une option existante ne se fait pas avec update_option() seul : cette fonction ne modifie l’autoload que si on le lui précise explicitement, et encore, cela dépend de la version de WordPress. La méthode fiable reste wp_set_option_autoload(), disponible depuis WordPress 6.4, ou à défaut une mise à jour directe via update_option( $name, $value, false ) qui repositionne l’autoload à 'no' lors du prochain enregistrement.

// Corrige l'autoload d'une option existante sans toucher sa valeur.
function mon_extension_desactiver_autoload_historique() {
$valeur = get_option( 'fidelite_historique_points' );
if ( false !== $valeur ) {
update_option( 'fidelite_historique_points', $valeur, false );
}
}
add_action( 'admin_init', 'mon_extension_desactiver_autoload_historique' );
Cette correction ne suffit toutefois qu’une fois : si l’extension continue d’appeler update_option() sans préciser l’autoload à chaque écriture ultérieure, certaines versions de WordPress peuvent réinitialiser la valeur à 'yes'. Il faut donc corriger l’appel d’origine dans le code de l’extension, pas seulement l’option en base.
Les critères pour trancher
- L’option est-elle lue sur chaque page front, y compris pour les visiteurs anonymes ? Si oui, l’autoload à
'yes'reste justifié. - L’option n’est-elle consultée que dans l’administration, dans une tâche cron, ou sur une action ponctuelle ? Alors l’autoload à
'no's’impose, quitte à appelerget_option()explicitement là où c’est nécessaire. - L’option grossit-elle avec l’activité du site, comme un historique, un journal ou un cache de résultats ? C’est le signal le plus fiable qu’elle ne devrait jamais avoir été autoloadée dès le départ.
Le cas particulier des options sérialisées volumineuses
Certaines extensions stockent un tableau PHP entier sérialisé dans une seule option, plutôt que plusieurs entrées distinctes. Ce choix aggrave le problème : impossible de désactiver l’autoload sur une partie seulement du tableau. La bonne pratique consiste à séparer, dès la conception, ce qui doit être disponible partout de ce qui ne sert que ponctuellement, plutôt que de tout regrouper dans une option fourre-tout.
Sur nos audits, une règle simple économise beaucoup de temps : toute option qui dépasse quelques kilo-octets mérite qu’on se demande pourquoi elle est encore autoloadée, avant même de chercher à l’optimiser autrement.
Mesurer le gain obtenu
Après correction sur le site de fidélité cité plus haut, l’autoload total est passé de 180 à 94 kilo-octets, avec une réduction mesurable du temps de génération des pages non cachées, de l’ordre de 8 millisecondes en moyenne sur l’échantillon suivi pendant une semaine. Ce chiffre paraît modeste isolément, mais il se cumule avec les autres optimisations, et il ne coûte qu’une poignée de lignes de code à corriger.
Pour aller plus loin
Cette chasse à l’autoload gagne à devenir un réflexe de revue de code plutôt qu’un audit ponctuel : à chaque nouvel add_option() introduit dans une extension, la question du troisième paramètre devrait se poser systématiquement, avant que l’option n’ait le temps de grossir en production. Un simple commentaire dans le code, expliquant pourquoi l’autoload a été choisi ainsi, évite qu’un développeur suivant ne revienne en arrière par réflexe.