Le WordPress d'aujourd'hui, décodé pour les développeurs

Performance

Purger sélectivement Algolia après une mise à jour d’un champ ACF

Réindexer les 60 000 fiches d'un catalogue à chaque modification d'un champ ACF est inutilement coûteux. Un snippet ciblé ne pousse vers Algolia que les enregistrements réellement modifiés.

Par WordPress Développement • 5 juillet 2022 • 4 min de lecture • Aucun commentaire
Purger sélectivement Algolia après une mise à jour d'un champ ACF

Modifier un seul champ ACF sur une seule fiche produit ne justifie jamais de relancer une réindexation complète des 60 000 enregistrements du catalogue vers Algolia. C’est pourtant le comportement observé par défaut sur ce projet avant intervention : chaque sauvegarde d’un champ personnalisé (qu’il s’agisse du prix, du stock ou d’une simple note interne) déclenchait une tâche de réindexation globale, consommant inutilement du quota d’opérations sur le plan Algolia et ralentissant l’interface d’administration pendant plusieurs secondes après chaque sauvegarde.

Le problème initial

L’extension d’intégration Algolia installée sur ce projet écoutait le hook générique save_post, sans distinguer si la modification concernait un champ ACF réellement indexé ou un réglage sans rapport avec le contenu de recherche. Pire, dans sa configuration par défaut, elle relançait une synchronisation complète du type de contenu concerné plutôt qu’une mise à jour ciblée sur l’enregistrement modifié, un comportement hérité d’une configuration copiée d’un projet précédent sans être adaptée à l’échelle de ce catalogue.

Le snippet ciblé

La correction consiste à écouter spécifiquement le hook acf/save_post, déclenché après la sauvegarde des champs personnalisés d’une fiche, et à ne transmettre à Algolia que l’enregistrement concerné, via saveObject plutôt qu’une réindexation globale :

add_action( 'acf/save_post', function ( $post_id ) {
    // Ignorer les types de contenu qui ne sont pas dans l'index
    if ( 'produit' !== get_post_type( $post_id ) ) {
        return;
    }

    $index = algolia_get_client()->initIndex( 'catalogue_produits' );
    $record = build_algolia_record_from_post( $post_id );

    $index->saveObject( $record, [ 'objectIDKey' => 'objectID' ] );
}, 20 ); // priorité 20, après que tous les champs ACF soient sauvegardés
L'essentiel à retenir : Une réindexation totale pour un seul champ modifié gaspille du quota API ; Le hook acf/save_post permet de cibler précisément l'enregistrement modifié ; Un debounce évite les envois multiples sur une modification en rafale

Éviter les envois multiples sur une modification en rafale

Un cas particulier a été observé lors d’imports en masse via un tableau ACF répétable : chaque ligne du tableau déclenchait indépendamment le hook, ce qui aurait multiplié les appels à saveObject pour un seul enregistrement modifié plusieurs fois en quelques secondes. Un mécanisme de regroupement par transient a été ajouté pour ne déclencher l’envoi qu’une fois le traitement terminé :

add_action( 'acf/save_post', function ( $post_id ) {
    if ( 'produit' !== get_post_type( $post_id ) ) {
        return;
    }

    $debounce_key = 'algolia_sync_pending_' . $post_id;
    if ( get_transient( $debounce_key ) ) {
        return; // un envoi est déjà planifié pour cette fiche
    }
    set_transient( $debounce_key, true, 30 );

    as_schedule_single_action(
        time() + 10,
        'envoyer_produit_vers_algolia',
        [ 'post_id' => $post_id ]
    );
}, 20 );

add_action( 'envoyer_produit_vers_algolia', function ( $post_id ) {
    $index = algolia_get_client()->initIndex( 'catalogue_produits' );
    $record = build_algolia_record_from_post( $post_id );
    $index->saveObject( $record, [ 'objectIDKey' => 'objectID' ] );
    delete_transient( 'algolia_sync_pending_' . $post_id );
});

Résultat mesuré sur le quota Algolia

Avant cette correction, une simple mise à jour de stock en masse sur une centaine de références (un import fournisseur classique sur ce catalogue) déclenchait la réindexation complète des 60 000 fiches, soit près de 60 000 opérations facturées côté Algolia pour une centaine de modifications réelles. Après la mise en place du snippet ciblé, le même import ne déclenche plus que les appels correspondant strictement aux fiches modifiées, ramenant le nombre d’opérations à un ordre de grandeur cohérent avec l’action réellement effectuée.

Variantes selon le contexte

  • Si le champ ACF modifié n’a aucun impact sur les données indexées (une note interne par exemple), le hook peut vérifier explicitement le nom du champ modifié via acf/update_value plutôt que de traiter toute sauvegarde comme pertinente.
  • Sur un import en masse programmatique (via update_field() appelé en boucle dans un script), le hook acf/save_post ne se déclenche pas automatiquement : un appel explicite à la fonction de synchronisation doit être ajouté à la fin du script d’import.

Réindexer l’intégralité d’un catalogue pour une seule fiche modifiée n’est jamais un excès de prudence : c’est un gaspillage de quota qui finit par coûter cher, littéralement, sur la facture du service tiers.

En résumé

Cibler précisément l’enregistrement modifié via acf/save_post et saveObject, plutôt que de relancer une synchronisation complète à chaque sauvegarde, réduit drastiquement le nombre d’opérations facturées par Algolia sur un catalogue de 60 000 fiches. Le mécanisme de regroupement par transient complète cette approche en évitant les envois redondants lors de modifications rapprochées sur une même fiche.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi