Ce qu’on observe
Un cabinet de développement pressé, sous contrainte de délai, accroche un traitement lourd sur le hook save_post : dès qu’un article est enregistré, quel que soit le champ modifié, une fonction régénère l’ensemble des tailles de miniatures associées aux images du contenu, « pour être sûr que tout soit à jour ». Le champ modifié peut être un simple sous-titre texte, sans aucun rapport avec une image : le traitement se déclenche quand même, systématiquement.
Ce schéma se repère facilement dans un profilage : chaque enregistrement d’article, y compris pour des corrections purement rédactionnelles, provoque un pic de charge CPU disproportionné par rapport à l’ampleur réelle de la modification effectuée.
Pourquoi c’est un problème
Régénérer des miniatures consiste à redécouper une image source dans plusieurs tailles définies par le thème, une opération qui sollicite fortement le processeur, en particulier sur un hébergement mutualisé où les ressources sont partagées avec d’autres sites. Déclencher cette opération à chaque enregistrement, sans condition sur le champ réellement modifié, revient à payer ce coût pour un résultat identique neuf fois sur dix : l’image n’a pas changé, donc les miniatures régénérées sont rigoureusement les mêmes que celles déjà en place.

Sur un site avec plusieurs auteurs enregistrant fréquemment des brouillons intermédiaires, le hook save_post peut se déclencher des dizaines de fois par jour, faisant de cet antipattern un poste de charge CPU disproportionné au regard de l’utilité réelle du traitement.
Quoi faire à la place
La correction consiste à cibler précisément le champ concerné plutôt que l’ensemble de l’enregistrement de l’article. Avec ACF, le hook acf/save_post combiné à une comparaison de la valeur précédente et nouvelle du champ image permet de ne déclencher la régénération que lorsque l’image a réellement changé :
add_action( 'acf/save_post', 'projet_regenerer_si_image_changee', 20 );
function projet_regenerer_si_image_changee( $post_id ) {
$ancienne = get_post_meta( $post_id, '_ancienne_image_id', true );
$nouvelle = get_field( 'image_principale', $post_id );
if ( $nouvelle && (int) $ancienne !== (int) $nouvelle ) {
projet_regenerer_miniatures( $nouvelle );
update_post_meta( $post_id, '_ancienne_image_id', $nouvelle );
}
}
Ce correctif ramène le déclenchement à sa juste cause : seule une modification effective de l’image entraîne une régénération, tout le reste passe sans surcoût.
Comment vérifier que le correctif fonctionne
- Enregistrer un article en modifiant uniquement un champ texte : aucune régénération ne doit se produire.
- Changer l’image principale : la régénération doit se déclencher, une seule fois.
- Surveiller la charge CPU sur une journée type après déploiement, en comparaison avec la période précédente.
Un antipattern voisin, à surveiller également
Le même raisonnement s’applique à d’autres traitements accrochés par facilité sur un hook trop large : purge complète du cache d’une page de listing à chaque enregistrement d’un article isolé, réindexation intégrale d’un moteur de recherche interne pour la modification d’une seule fiche, ou recalcul d’un flux de syndication entier alors qu’un seul élément a changé. Dans chacun de ces cas, le symptôme et le remède se ressemblent : identifier le déclencheur réellement pertinent, et comparer explicitement l’état avant et après modification avant de lancer un traitement coûteux.
Ce réflexe de comparaison avant déclenchement, une fois pris, évite la plupart des antipatterns de ce type, quel que soit le traitement concerné derrière le hook choisi.
Un hook large qui « fonctionne » n’est pas la même chose qu’un hook qui fait exactement ce qu’il faut : le premier finit toujours par coûter cher quand le trafic augmente.
En résumé
Accrocher un traitement lourd sur un hook générique par facilité, plutôt que de cibler le champ réellement concerné, revient à payer un coût CPU récurrent pour un résultat identique la plupart du temps. Une invalidation ciblée, comparant l’ancienne et la nouvelle valeur du champ avant de déclencher quoi que ce soit, règle le problème à sa racine sans complexifier significativement le code.