Filtre de produits AJAX : catalogue pratique sans rechargement de page
Le filtrage WooCommerce standard recharge la page à chaque clic et perd les options sélectionnées. Un filtre AJAX avec un indice pré-calculé prend 50 ms, affiche la couleur avec un cercle, la marque avec un logo et au lieu de la pagination, il y a un bouton « Afficher plus ».
COS / KNOWLEDGE BASE
Il y a trois ans, le propriétaire d'un magasin de pièces automobiles en ligne m'a appelé et m'a dit une phrase que j'entends régulièrement depuis : « Nous avons un catalogue de quinze mille articles, et les gens partent sans trouver le bon produit ». Je suis allé sur son site Internet, j'ai sélectionné la marque de la voiture dans le filtre - la page s'est rechargée. Sélectionnez le type de pièce de rechange - redémarrez à nouveau. J'ai essayé de spécifier la fourchette de prix - un autre redémarrage et tous les filtres précédents ont été réinitialisés. Trois clics - quinze secondes d'attente et une perte totale de contexte. J'ai fermé l'onglet. Et je suis une personne qui s'occupe professionnellement des boutiques en ligne. Que fait l’acheteur moyen ? C'est vrai, il va à Wildberries, où le filtrage fonctionne instantanément.
Ce n'est pas l'histoire d'un seul magasin. Il s'agit d'un problème systémique avec WooCommerce, que je vois dans presque tous les projets où un filtre AJAX normal n'a pas encore été installé. Le mécanisme de filtrage standard de WooCommerce est extrêmement simple : vous sélectionnez un paramètre, le navigateur envoie une requête GET avec les nouveaux paramètres, le serveur traite l'intégralité de la requête - de l'analyse de l'URL au rendu de la page HTML complète - et renvoie le résultat. Pour chaque clic sur le filtre, il y a un cycle complet : interroger la base de données, assembler le modèle, renvoyer tout le HTML au navigateur. Et si vous avez dix mille produits, chacun avec une douzaine d'attributs, et que, de plus, le serveur n'est pas le meilleur, chacun de ces redémarrages peut prendre deux ou trois secondes. Multipliez cela par les cinq à six clics nécessaires pour affiner la sélection aux produits souhaités, et vous obtenez quinze à vingt secondes de temps d'attente pur. Pendant ce temps, l'acheteur a le temps de changer d'avis, de se distraire ou simplement de partir.
J'ai étudié ce problème pendant longtemps - non pas en tant que développeur, mais en tant que spécialiste du marketing. Car pour un marketeur, le filtrage du catalogue n’est pas un détail technique, mais un élément essentiel de l’entonnoir de vente. Entre « allé au catalogue » et « ajouté au panier », il y a un filtre, et s'il fonctionne mal, l'entonnoir coule ici. Selon le Baymard Institute, 42 % des grands détaillants en ligne perdent des clients en raison d'un filtrage peu pratique. Pas à cause des prix, ni à cause de l'assortiment - parce qu'une personne ne peut pas trouver rapidement ce dont elle a besoin. Et lorsque j'ai commencé à concevoir le module de filtration pour notre plugin, je me suis fixé une tâche : m'assurer que l'acheteur ne remarque même pas que le filtre fonctionne. Pas de redémarrage, pas de décalage, pas de sentiment de « J'attends que l'ordinateur réfléchisse ».
Voici ce qui en est arrivé - et pourquoi, sous le capot, cela s'est avéré beaucoup plus compliqué qu'il n'y paraît à première vue.
Pourquoi le filtrage standard WooCommerce est pénible
Pour comprendre pourquoi un filtre AJAX n'est pas seulement une fonctionnalité intéressante, mais une nécessité, regardons ce qui se passe lorsqu'un acheteur filtre les produits dans WooCommerce standard. Disons que vous avez un magasin d'huiles industrielles. Un acheteur entre dans un catalogue, voit huit cents produits et souhaite choisir une huile moteur 5W-30 d’une certaine marque. Il clique sur le widget « Filtrer par attribut », sélectionne « Huiles moteur » - et la page est complètement rechargée. Le navigateur envoie une requête GET du type « ?filter_tip-masla=motornoe », le serveur la traite, WooCommerce lance WP_Query avec des méta-requêtes, MySQL parcourt wp_postmeta - une table qui peut peser jusqu'à un gigaoctet sur un projet de seize mille produits - et renvoie le résultat en quelques secondes. L'acheteur voit, disons, trois cents produits. Il souhaite maintenant sélectionner la viscosité. Un autre clic - un autre redémarrage, encore deux secondes. Puis la marque - le troisième redémarrage. Et voici le plus ennuyeux : sur certains thèmes et configurations, les filtres précédents sont réinitialisés au prochain redémarrage. L’acheteur recommence.
J'ai vu cela des dizaines de fois sur des projets réels. Le propriétaire du magasin investit de l'argent dans la publicité, paie pour chaque clic dans Yandex.Direct, amène une personne sur le site - et la perd au stade du filtrage. Et non pas parce qu'il n'y a pas de produit, mais parce qu'il y a un produit, mais qu'il est normalement impossible de le trouver. C'est comme un magasin où toutes les marchandises sont empilées en une seule pile et où le vendeur répond à chaque question avec un délai de trois secondes. Voudrais-tu partir ? Je serais parti.
Il y a un autre problème dont on parle peu : le filtrage par défaut de WooCommerce est très mauvais pour le référencement. Chaque option de filtre génère une URL unique avec des paramètres GET, et si un robot de recherche commence à indexer toutes ces combinaisons (et il peut y avoir dix puissances dix de combinaisons avec dix attributs avec dix valeurs chacune) vous vous retrouvez avec un index gonflé, du contenu en double et un budget d'exploration dilué. Pour un petit magasin avec des centaines de produits, ce n'est pas critique, mais pour un catalogue sérieux, c'est un vrai problème.
En fait, c'est pourquoi tous les principaux marchés - Ozon, Wildberries, Yandex.Market - sont depuis longtemps passés au filtrage AJAX. Lorsqu'un client sélectionne une option, le navigateur envoie une requête asynchrone au serveur, reçoit uniquement les données (pas d'en-tête, de pied de page ou de barre latérale) et met à jour uniquement la partie de la page où les produits sont affichés. Pas de scintillement d'écran, pas de redémarrage, pas de perte de défilement. Vous cliquez et les produits changent instantanément. Il s'agit d'une norme de l'industrie, et si votre magasin ne la propose pas, vous perdez déjà au niveau de l'expérience utilisateur.
Mais - et c'est là que les choses deviennent intéressantes - il ne suffit pas de simplement passer le filtrage à AJAX. Si le même WP_Query avec les jointures wp_postmeta reste sous le capot, vous supprimerez simplement le rechargement, mais la vitesse de réponse restera la même - la même d'une seconde et demie à deux pour chaque demande. L’acheteur ne verra pas la page se recharger, mais verra un spinner à la place de la liste des produits. Et la différence entre « la page se recharge » et « les produits n'apparaissent pas » en termes de patience des clients est approximativement nulle. Par conséquent, lors de la conception de notre module de filtrage, j'ai immédiatement adopté une approche radicalement différente en matière de stockage et de récupération des données.
FilterIndex : quand cinquante millisecondes ce n'est pas du marketing, mais la réalité
L'idée principale qui distingue notre filtre AJAX de la plupart des solutions du marché est l'index pré-calculé. Il s’appelle FilterIndex et fonctionne sur le principe utilisé par les moteurs de recherche : au lieu de parcourir tous les produits et leurs attributs à chaque fois qu’un utilisateur le demande, on construit à l’avance un tableau optimisé qui possède déjà tous les liens nécessaires « produit – attribut – valeur – prix – disponibilité ».
Comment ça marche techniquement ? Lorsqu'un administrateur configure des filtres (par exemple, en ajoutant un filtrage par marque, viscosité et type d'huile), le système lance une tâche en arrière-plan via le planificateur d'actions. Cette tâche parcourt tous les produits du catalogue et enregistre pour chaque produit un ensemble de lignes dans une table wpaic_filter_index distincte : produit tel ou tel, l'attribut « Marque », la valeur « Shell » ; produit tel ou tel, attribut « Viscosité », valeur « 5W-30 » ; et ainsi de suite. De plus, le prix du produit, l'état de disponibilité, la catégorie et d'autres informations pouvant être nécessaires au filtrage sont ajoutés à chaque ligne. Essentiellement, nous prenons des données dispersées dans des dizaines de tables WordPress – wp_posts, wp_postmeta, wp_terms, wp_term_relationships, wp_wc_product_meta_lookup – et les plaçons dans une seule table plate avec les index corrects.
Résultat ? Une requête qui, dans le filtrage WooCommerce standard, nécessitait quatre à cinq opérations JOIN sur la table wp_postmeta de la taille d'un gigaoctet et était complétée en une seconde et demie à deux secondes, est désormais complétée en trente à cinquante millisecondes. Il ne s’agit pas d’un chiffre théorique, mais de mesures réelles sur un catalogue de seize mille produits comportant quatre-vingt-dix-neuf attributs. La différence de vitesse est de trente à quarante fois. Et l'acheteur ressent littéralement cette différence : il clique sur le filtre - et la marchandise apparaît instantanément, sans aucune attente.
Mais un index précalculé pose une question évidente : que se passe-t-il si les données ont changé ? Vous avez ajouté un nouveau produit, modifié le prix, mis à jour les soldes de 1C ? C’est là qu’intervient le système de crochets. Lorsque vous modifiez un produit - via l'édition standard dans WordPress, via l'API REST, via l'importation depuis 1C - un hook est déclenché qui met à jour les lignes correspondantes dans l'index. De plus, il ne met pas à jour l’intégralité de l’index, mais uniquement les lignes d’un produit spécifique. Une reconstruction complète de l'index est lancée uniquement sur commande de l'administrateur ou selon un planning - par exemple, une fois par jour pour garantir la cohérence. En mode normal, l'index est mis à jour progressivement, presque en temps réel.
Je me souviens d'un client, propriétaire d'un magasin de vingt mille produits, qui me demandait : « Êtes-vous sûr que l'index ne se désynchronisera pas ? C'est une bonne question - je me l'ai posée moi-même dès la phase de conception. Et la réponse est : oui, dans certaines circonstances - par exemple, lors de la modification directe de la base de données via WordPress - l'index peut être en retard. C'est pourquoi dans le panneau de configuration il y a un bouton pour reconstruire manuellement l'index et configurer la reconstruction automatique via cron. Mais en mode normal, lorsque les produits sont modifiés via WooCommerce ou via notre connecteur 1C, la désynchronisation est exclue.
Autre point qui me semble important : l'index stocke non seulement les valeurs des attributs, mais aussi le nombre de produits pour chaque valeur. C'est ce qu'on appelle des « compteurs à facettes » : lorsqu'à côté de chaque valeur de filtre, le nombre de produits qui lui correspondent est affiché. Dans le filtrage WooCommerce standard, ces compteurs ne sont pas affichés ou nécessitent une requête supplémentaire dans la base de données. Dans notre cas, les compteurs sont calculés au moment de la demande, pratiquement sans frais supplémentaires, car l'index contient déjà toutes les informations nécessaires. Et lorsque l'acheteur sélectionne « Shell » dans le filtre par marque, il voit immédiatement qu'il existe douze huiles moteur Shell d'une viscosité de 5W-30, et huit d'une viscosité de 10W-40. Cela élimine la situation « paramètre sélectionné - résultat nul », qui irrite énormément les acheteurs.
En parlant de résultat nul. L'un des problèmes du filtrage standard réside dans ce que l'on appelle les « combinaisons mortes ». L'acheteur sélectionne la marque, puis le type d'huile, puis la viscosité - et reçoit une page blanche, car il n'existe aucun produit avec cette combinaison de paramètres. Dans notre filtre, les combinaisons mortes sont automatiquement bloquées : après chaque sélection de paramètre, les compteurs de toutes les autres valeurs sont recalculés et les valeurs avec des produits nuls sont soit masquées, soit affichées inactives. L'acheteur ne peut physiquement pas accéder à une sélection vide - le système le guide, lui montrant uniquement les options pertinentes.
Filtres et swatches visuels : quand l'interface fait vendre
Honnêtement, la vitesse de filtration est fondamentale, mais ce n'est pas ce que l'acheteur remarque en premier. La première chose qui attire l’attention est l’apparence des filtres. Et ici, avec WooCommerce standard, tout est complètement triste : des listes déroulantes avec des valeurs de texte. "Rouge", "Bleu", "Vert" - écrits dans le texte. Imaginez maintenant que vous vendez de la peinture, du tissu, des meubles ou des vêtements. L’acheteur doit voir la couleur, pas lire son nom. Il veut cliquer sur le cercle rouge et voir tous les produits rouges. Ou cliquez sur le logo Bosch et voyez tout ce qui concerne Bosch, sans vous rappeler comment épeler le nom - Bosch, BOSCH ou Bosch.
Nous avons implémenté trois types de filtres visuels. Le premier concerne les échantillons de couleurs. Chaque valeur de l'attribut « Couleur » peut se voir attribuer un code couleur HEX, et dans le filtre, au lieu d'une liste de textes, l'acheteur voit une série de cercles colorés. J'ai cliqué sur le rouge et reçu des marchandises rouges. De plus, les cercles ne sont pas seulement statiques : la couleur sélectionnée est mise en évidence par un cadre et, lorsque vous les survolez, une info-bulle avec le nom s'affiche. Le deuxième type est celui des boutons. Cela fonctionne bien pour les tailles (S, M, L, XL, XXL) ou les tailles discrètes (500 ml, 1 L, 5 L, 20 L). Au lieu d'une liste déroulante, il existe une série de boutons soignés sur lesquels vous pouvez cliquer et combiner. Le troisième type est celui des logos. Pour l'attribut Marque, chaque valeur peut être chargée avec une image de logo et l'acheteur choisit la marque par image visuelle plutôt que par texte. Ceci est particulièrement important pour les magasins de marques internationales, où le client peut avoir une meilleure mémoire visuelle du logo que de l'orthographe du nom.
Et ici, je souhaite me concentrer spécifiquement sur les échantillons non pas dans le filtre, mais sur la fiche produit. Parce qu'il s'agit d'une tâche connexe mais distincte. Lorsque l'acheteur trouve un produit via le filtre et accède à la carte, il doit sélectionner une option spécifique. Couleur, taille, volume – dans WooCommerce, cela est implémenté via des produits variables et des listes déroulantes standard. Et ces listes sont l’une des plus grandes opportunités manquées de WooCommerce en termes de conversion.
Notre module swatch remplace les listes déroulantes par des éléments visuels directement sur la fiche produit. Pour la couleur - des cercles avec de vraies couleurs. Pour la taille - boutons. Pour la marque - miniatures de logo. Mais le plus important est que lorsque vous sélectionnez une option, l’image du produit change automatiquement. L'acheteur clique sur le cercle bleu - et la version bleue apparaît sur la photo principale du produit. Clique sur le rouge - voit du rouge. C’est une petite chose d’un point de vue technique, mais d’un point de vue marketing c’est un énorme levier. Un acheteur qui voit un produit dans la couleur qu’il souhaite est beaucoup plus proche de l’achat qu’une personne qui ne voit que le texte « Bleu » et doit imaginer à quoi il ressemble.
J'ai mené des recherches informelles sur trois projets dans lesquels nous avons implémenté des échantillons. Avant la mise en œuvre, la conversion de la fiche produit en panier était en moyenne de huit pour cent. Après l'introduction d'échantillons visuels avec changements d'image automatiques - onze à douze pour cent. Une augmentation de trente à cinquante pour cent. Il est clair qu’il ne s’agit pas d’un pur test A/B et qu’il y a d’autres facteurs à prendre en compte, mais la tendance est claire. Les gens achètent ce qu’ils voient, pas ce qu’ils lisent.
Autre nuance qui me semble importante : les swatches et les filtres visuels doivent constituer un seul système. Si dans le filtre du catalogue « rouge » se trouve un cercle de couleur #FF0000, et sur la fiche produit « rouge » le texte dans la liste déroulante, l'acheteur se sent déconnecté. Dans notre plugin, les paramètres des échantillons sont globaux : vous attribuez une fois le type d'affichage « Échantillon de couleur » à l'attribut « Couleur » et définissez des codes HEX pour chaque valeur - puis ces échantillons sont utilisés partout : dans le filtre, sur la fiche produit, dans les widgets, dans les résultats de recherche. Un décor - un langage visuel unique dans tout le magasin.
Mais parlons de ce qui se passe sous la liste de produits : la pagination. Parce que même un filtre idéal n'aidera pas s'il reste deux cents produits après le filtrage et que l'acheteur doit changer de page pour tous les voir.
« Afficher plus » au lieu de la pagination : petit bouton, gros effet
Savez-vous ce qui m'a toujours surpris à propos de WooCommerce ? La pagination standard - « 1, 2, 3, ... 15, Suivant » - a été inventée à une époque où chaque page était entièrement chargée et où l'utilisateur était assis devant un bureau avec une souris. Aujourd'hui, plus de soixante pour cent des clients proviennent d'appareils mobiles et pour eux, changer de page est pénible. Des petits liens qu'il faut appuyer avec le doigt, et chaque transition signifie un rechargement de page, plus une perte de position de défilement. Ozon et Wildberries l'ont remplacé il y a longtemps par un bouton « Afficher plus » et un chargement sans fin, et ce n'est pas une coïncidence : c'est simplement plus pratique.
Dans notre plugin, nous avons implémenté le module Load More, qui remplace la pagination standard de WooCommerce par un bouton « Afficher plus ». L'acheteur a fait défiler jusqu'à la fin de la portion actuelle de marchandises, a appuyé sur un gros bouton - et la portion suivante est ajoutée en douceur à celles déjà chargées. Pas de rechargement, pas de perte de scroll, pas besoin de viser des petits numéros de pagination. Et cela fonctionne très bien en conjonction avec le filtre AJAX : l'acheteur a sélectionné les paramètres, a vu les vingt premiers produits, a cliqué sur « Afficher plus » et en a vu vingt autres. Tout sur une seule page, tout sans scintillement.
Techniquement, cela fonctionne comme ceci : lorsqu'un bouton est cliqué, JavaScript envoie une requête AJAX avec les options de filtrage actuelles et le numéro de « page » suivant. Le serveur renvoie le balisage HTML pour le prochain lot de produits et le script l'insère dans le DOM après le dernier produit. L'URL dans la barre d'adresse ne change pas, le défilement est conservé et les filtres sélectionnés restent en place. Pour l’acheteur, il semble que les articles « apparaissent » simplement au bas de la liste.
Mais il y a une subtilité dont je souhaite parler, car de nombreux développeurs tombent dessus. Lorsque vous utilisez le chargement infini sur WooCommerce, vous devez gérer correctement la situation lorsque vous manquez de produits. Si l'acheteur a atteint la dernière partie, le bouton « Afficher plus » devrait disparaître et il est conseillé d'afficher un message discret « Tous les produits sont chargés ». Cela semble trivial, mais j'ai vu des implémentations dans lesquelles le bouton continuait à s'afficher et renvoyait une réponse vide lorsqu'il était cliqué, laissant le client confus. Ou, à l'inverse, le bouton a disparu, mais lors du changement de filtre, il n'est pas réapparu et l'acheteur n'a vu que les vingt premiers produits sur deux cents. Dans notre module, le bouton est contrôlé par l'état : il sait combien de produits il reste et le montre à l'acheteur - "Afficher plus (45 restants)". Lorsque les filtres sont changés, le compteur est réinitialisé et recalculé automatiquement.
Il y a encore une chose qui, à mon avis, est essentielle pour les utilisateurs mobiles : la taille et l'emplacement des boutons. Les liens de pagination WooCommerce standard sont de petits nombres difficiles à atteindre avec le doigt sur un téléphone. Notre bouton Afficher plus est un bouton pleine largeur avec un texte de grande taille que vous ne pouvez pas manquer. Il est stylisé pour correspondre à la conception globale du magasin via des variables CSS, et l'administrateur peut personnaliser sa couleur, ses arrondis et ses indentations - mais par défaut, il a déjà fière allure et, plus important encore, il est facile de cliquer dessus depuis n'importe quel appareil.
Et cela soulève une question qu'on me pose régulièrement : qu'en est-il du SEO ? Si tous les produits sont chargés via AJAX, comment les robots de recherche verront-ils le catalogue complet ? C’est une question vraiment importante, et la réponse réside dans l’architecture. Notre module Load More ne remplace pas la pagination côté serveur, mais la complète. Le code HTML de la page contient des liens standards vers les pages suivantes - rel="next" et rel="prev". Un robot de recherche qui n'exécute pas JavaScript suit ces liens et indexe toutes les pages de l'annuaire comme d'habitude. Et l'acheteur, dont JavaScript est en cours d'exécution, voit un bouton « Afficher plus » au lieu des liens de pagination et charge les produits via AJAX. Ainsi, nous obtenons le meilleur des deux mondes : une UX pratique pour l’acheteur et une indexation complète pour le robot de recherche.
Au fait, à propos de la combinaison du filtre et du chargement. Lorsque l'acheteur modifie les paramètres du filtre, le module Charger plus est automatiquement réinitialisé : la première partie des produits selon les nouveaux critères est affichée, le compteur est réinitialisé et le bouton met à jour le nombre de produits restants. Cela semble évident, mais en pratique, l'intégration des deux modules AJAX (filtrage et chargement) nécessite une coordination minutieuse. Ils doivent utiliser un état commun et nous avons passé beaucoup de temps à rendre cette connexion transparente.
Parlons maintenant de la façon dont tout cela fonctionne sur les appareils mobiles. Parce que le filtrage mobile est une autre histoire, avec ses propres problèmes et solutions.
Sur ordinateur, les filtres sont généralement situés dans la barre latérale à gauche de la liste des produits. L'écran est grand, il y a suffisamment d'espace, le panneau de filtrage est toujours visible - cliquez et sélectionnez. Un tel luxe n’existe pas sur mobile. La barre latérale ne rentre tout simplement pas à côté des produits sur un écran de trois cent quatre-vingt-dix pixels de large. Et ici, il existe deux solutions typiques, toutes deux infructueuses. La première consiste à afficher des filtres au-dessus des produits, une longue liste. L'acheteur voit un écran rempli de filtres et doit les parcourir pour voir au moins un produit. La seconde consiste à masquer les filtres dans un élément accordéon standard ou un bloc déroulant. L'acheteur clique - les filtres s'ouvrent, mais en même temps, ils déplacent les produits vers le bas et tout saute à l'écran.
Nous avons choisi la troisième voie : un panneau filtrant pliable sous forme de superposition. Sur un appareil mobile, l'acheteur voit un bouton « Filtres » - généralement en haut du catalogue, à côté du tri et de la quantité des produits. Lorsque vous cliquez sur ce bouton, le panneau de filtre glisse sur le côté - comme un menu sur de nombreux sites mobiles - et occupe environ quatre-vingts pour cent de l'écran. L'acheteur sélectionne les paramètres nécessaires, clique sur « Afficher » - le panneau se ferme et les produits sont mis à jour. Il est important que dans ce cas les produits soient mis à jour en temps réel, juste pendant que le panneau est ouvert : l'acheteur voit le compteur « Trouvé : 42 produits » sur le bouton « Afficher », et ce compteur est mis à jour à chaque changement de filtre. Cela permet à l'acheteur de savoir immédiatement s'il restreint trop sa sélection ou non.
Une autre astuce que nous utilisons sur mobile consiste à utiliser les « puces » des filtres sélectionnés. Après avoir fermé le panneau de filtrage, des « chips » compactes apparaissent au-dessus de la liste des produits - de petites barres avec les valeurs sélectionnées : « Shell », « 5W-30 », « En stock ». Chaque puce peut être retirée d'un seul clic en retirant le filtre correspondant. C'est beaucoup plus pratique que d'ouvrir à nouveau le panneau pour supprimer un paramètre. Et cela fait gagner du temps à l'acheteur - et le temps passé sur mobile est doublement précieux, car les sessions mobiles sont généralement plus courtes que celles sur ordinateur.
Une chose intéressante que j'ai remarquée est que sur les appareils mobiles, les consommateurs utilisent en moyenne moins de filtres à la fois - généralement un ou deux, trois au maximum. Mais ils les utilisent plus souvent et plus rapidement. Par conséquent, la vitesse de réponse est essentielle : cinquante millisecondes de réponse d'index jouent ici un rôle encore plus important que sur le bureau. Si un client mobile clique sur un filtre et attend plus d’une seconde, il décidera très probablement que quelque chose est cassé et recommencera à cliquer. Et double-cliquer sur un filtre signifie généralement sélectionner et annuler immédiatement - et l'acheteur se retrouve là où il a commencé, seulement ennuyé.
Parlons maintenant d'une situation à laquelle de nombreux commerçants sont confrontés : migrer à partir d'une solution existante. Étant donné que la plupart des magasins WooCommerce ne sont pas construits à partir de zéro, ils disposent déjà d'une sorte de filtre, généralement YITH Ajax Product Filter ou WooCommerce Product Filter d'un autre développeur.
Migration depuis YITH et autres filtres : comment ne pas perdre de données et de nerfs
J'ai rencontré à plusieurs reprises une situation dans laquelle un magasin utilise YITH Ajax Product Filter depuis des années et le propriétaire souhaite passer à autre chose. Il y a différentes raisons : YITH a arrêté la mise à jour, a commencé à entrer en conflit avec le thème, fonctionne trop lentement sur un grand catalogue ou en a simplement marre de payer séparément pour un filtre, séparément pour les échantillons, séparément pour la pagination. Et la première question posée par le propriétaire : « Les paramètres du filtre seront-ils enregistrés ?
Soyons honnêtes : il n'y a pas de migration 100% automatique des paramètres entre les différents plugins de filtrage. Architectures trop différentes, manières de stocker la configuration trop différentes. YITH stocke ses préréglages dans les options WordPress et postmeta, d'autres plugins utilisent des tableaux personnalisés et d'autres utilisent des fichiers JSON. Mais vous n'avez pas non plus besoin de migrer manuellement : notre module dispose d'un outil de migration qui analyse les plugins de filtrage installés et propose un mappage des paramètres.
Comment cela fonctionne-t-il en pratique ? Lorsque vous activez pour la première fois notre module de filtrage, le système vérifie si YITH Ajax Product Filter (ou YITH WooCommerce Ajax Product Filter Premium) est installé. Si oui, l'onglet « Migration » apparaît dans l'interface des paramètres avec des informations sur les préréglages YITH trouvés, les filtres configurés et leurs types. L'administrateur voit quels attributs ont été configurés dans YITH, quels types d'affichage ont été utilisés (case à cocher, liste déroulante, échantillon de couleur, curseur de prix) et peut démarrer la migration avec un seul bouton. Le système crée des filtres similaires dans notre module, cartographie les types d'affichage (YITH « couleur » → notre « échantillon », YITH « étiquette » → notre « bouton » et ainsi de suite) et construit un index.
Mais je tiens à vous prévenir : après la migration, vous devez impérativement vérifier le résultat manuellement. Non pas parce que la migration n’est pas fiable, mais parce que c’est une excellente raison de reconsidérer la structure des filtres. Il arrive souvent que les filtres dans YITH aient été configurés il y a deux ou trois ans, depuis lors la plage a changé, de nouveaux attributs sont apparus, certaines valeurs sont obsolètes - et la migration copie aveuglément tout tel quel, y compris les paramètres qui ne sont plus pertinents. J'encourage les clients à utiliser la migration comme point de départ, puis à parcourir chaque filtre et à se demander : « Le client en a-t-il vraiment besoin ?
D'ailleurs, l'une des questions les plus courantes lors de la migration est « qu'arrivera-t-il à l'URL ? » YITH a son propre format pour filtrer les URL (généralement avec des hachages ou des paramètres personnalisés), tandis que notre module a le sien. Si vous avez activement utilisé le filtrage des URL dans les publicités ou les liens internes, ces URL ne fonctionneront plus lors de la migration. Dans de tels cas, je recommande de configurer des redirections via notre module de redirections SEO, qui prend en charge les modèles regex. Quelques règles - et les anciens liens de filtrage seront correctement redirigés vers les nouveaux.
Autre conseil pratique issu de l'expérience de migration : ne désactivez pas l'ancien filtre avant d'avoir entièrement configuré le nouveau. Cela semble évident, mais j'ai vu des gens désactiver YITH, activer notre module et commencer la configuration - pendant que le magasin en direct fonctionne sans aucun filtrage. Cela peut prendre une heure ou deux et pendant ce temps, vous perdrez certaines ventes. Il est préférable de mettre en place un nouveau filtre en parallèle (il n'entrera en conflit que lorsque son shortcode sera placé sur la page), de s'assurer que tout fonctionne et de switcher en même temps.
Je tiens encore une fois à souligner l'idée sur laquelle je reviens constamment : le filtrage de catalogue n'est pas une fonctionnalité technique, mais un élément commercial. Chaque magasin qui a migré du filtrage standard ou du plugin hérité de WooCommerce vers notre filtre de pré-index AJAX a constaté une amélioration des métriques comportementales. Taux de rebond réduit sur la page catalogue, profondeur de navigation augmentée, temps passé sur le site augmenté. Et, plus important encore, une augmentation des conversions depuis la consultation du catalogue jusqu’à l’ajout au panier. Parce que lorsqu’un client trouve rapidement ce dont il a besoin, il est plus susceptible de l’acheter.
Parlons maintenant de la façon dont tout cela est réuni en un seul système et pourquoi l'approche « un plugin pour tout » est ici d'une importance fondamentale.
Savez-vous quel est, à mon avis, le principal problème avec l'approche « filtre d'un développeur, échantillons d'un autre, pagination d'un troisième » ? Il ne s’agit pas de conflits de plugins, même s’ils surviennent également. C’est l’écart de l’expérience utilisateur. L'acheteur sélectionne une couleur dans le filtre et voit un beau cercle. Va à la fiche produit - et il y a une liste déroulante de texte. Clique sur « Afficher plus » - et les filtres sont réinitialisés, car le plugin de pagination ne connaît pas le plugin de filtrage. Chacun de ces plugins fonctionne très bien seul, mais ensemble, ils créent le sentiment de Frankenstein - assemblés à partir de différentes pièces, inégales, avec des coutures saillantes.
Lorsque le filtre, les échantillons, le chargement de produits et l'indexation font partie du même module, ils partagent un état commun. Le code JavaScript de filtrage connaît le module de chargement et interagit correctement avec lui. Les paramètres Swatch sont appliqués de la même manière dans le filtre et sur la fiche produit. L'index de filtrage prend en compte les données mises à jour via d'autres modules de plugin - synchronisation 1C, édition groupée, importation. Il ne s’agit pas seulement de commodité pour le développeur, mais également d’un niveau d’expérience utilisateur fondamentalement différent pour l’acheteur.
J'utilise souvent l'analogie d'une voiture. Vous pouvez assembler une voiture à partir de pièces de différents fabricants : un moteur de l'un, une suspension d'un autre, l'électronique d'un troisième. Techniquement, cela est possible et chaque détail peut être d'excellente qualité. Mais une voiture conçue dans son ensemble roulera mieux, car les ingénieurs ont optimisé l'interaction de tous les composants plutôt que chaque composant individuellement. C’est pareil avec une boutique en ligne : l’acheteur n’a pas besoin du meilleur filtre du monde, des meilleurs échantillons et de la meilleure pagination. Il a besoin d'un catalogue qui fonctionne dans son ensemble - rapidement, magnifiquement et de manière prévisible.
Et ici, je veux revenir au sujet avec lequel j'ai commencé : la vitesse. Parce que l'index précalculé n'est pas la seule optimisation que nous avons effectuée. Plusieurs autres facteurs affectent le taux de filtration perçu. Tout d’abord, une mise à jour optimiste : lorsqu’un acheteur clique sur un filtre, la grille de produits reçoit instantanément un effet de « chargement » CSS – une légère atténuation ou un léger flou – et une requête AJAX est envoyée en même temps. Lorsque la réponse arrive (au bout de trente à cinquante millisecondes - je vous le rappelle), les produits sont mis à jour et l'effet de chargement est supprimé. Pour l'acheteur, cela ressemble à une réaction instantanée : il a cliqué - la grille a « clignoté » - de nouveaux produits sont en place. De plus, il « a clignoté » si rapidement que l'acheteur ne le perçoit pas comme une attente, mais comme une confirmation visuelle de l'action.
Deuxièmement, la mise en cache côté client. Si l'acheteur a sélectionné « Shell, 5W-30 » et a reçu douze produits, puis a supprimé « 5W-30 » et a examiné toutes les huiles Shell, puis a mis à nouveau « 5W-30 » - la deuxième fois, la même demande n'ira pas au serveur, mais sera envoyée depuis le cache du navigateur. Cela permet d'économiser du trafic et d'accélérer la navigation lors du filtrage « retour » lorsque l'acheteur essaie différentes combinaisons dans les deux sens.
Troisièmement - et c'est peut-être l'optimisation la moins évidente - nous envoyons depuis le serveur non pas le HTML complet des fiches produits, mais le minimum requis. Un modèle de fiche produit WooCommerce standard dans un catalogue peut contenir des dizaines de hooks, chacun ajoutant du HTML : un bouton de comparaison d'un plugin, une icône de favoris d'un autre, une note d'un troisième. Sur une page contenant vingt produits, cela peut représenter deux ou trois cents kilo-octets de HTML. Nous avons optimisé le rendu du serveur pour que la réponse AJAX ne contienne que le minimum requis, et que des éléments supplémentaires (boutons de comparaison, échantillons, icônes) soient initialisés sur le client après insertion des cartes dans le DOM. Le résultat est que la réponse du serveur est trois à quatre fois plus facile, et avec un Internet mobile lent, la différence est notable.
Enfin, la dernière chose dont je veux parler est le filtrage des analyses. Nous avons intégré une collecte de statistiques dans le module de filtrage : quels filtres sont utilisés le plus souvent, quelles combinaisons sont sélectionnées, quelles valeurs ne sont jamais cliquées, combien de fois les acheteurs arrivent à un résultat nul. Ces données sont disponibles dans le panneau de contrôle et aident le propriétaire du magasin à optimiser le catalogue. Si vous constatez que le filtre « Pays de fabrication » est utilisé à zéro virgule deux pour cent du filtrage, il peut être intéressant de le supprimer pour ne pas encombrer le panneau. Si vous constatez que les clients filtrent souvent par marque et immédiatement par viscosité, il est logique de mettre ces deux filtres en premier. Si vous constatez que sur mobile, les clients n'utilisent que le curseur de prix et la marque, vous pouvez masquer les filtres restants pour la version mobile, en les affichant uniquement en appuyant séparément sur « Tous les filtres ».
Voici le problème : le filtrage de répertoires ne consiste pas à "le définir et à l'oublier". Il s’agit d’un outil vivant qui doit être personnalisé en fonction de votre gamme de produits et de vos clients. Et plus vous collectez de données sur la façon dont les acheteurs filtrent, plus vous pouvez personnaliser avec précision. Nous essayons de fournir au propriétaire du magasin non seulement un filtre, mais un outil permettant de comprendre comment les clients recherchent des produits.
Lorsque j'ai commencé à concevoir ce module, je me suis fixé un objectif simple : qu'un acheteur dans une boutique en ligne sur WooCommerce puisse trouver un produit aussi rapidement et facilement que sur Ozon ou Wildberries. Pas « presque pareil » ni « avec quelques restrictions », mais vraiment pareil. Filtrage instantané sans rechargement, échantillons visuels au lieu de listes de textes, chargement sans fin au lieu de pages numérotées, panneau de filtrage mobile pratique. Et pour que tout cela fonctionne rapidement - pas en quelques secondes, mais en dizaines de millisecondes.
Est-ce que ça a fonctionné ? Je le pense - mais pas parce que nous avons écrit un code brillant, mais parce que nous avons correctement défini nos priorités. Nous n'avons pas commencé avec une belle interface, mais avec des performances - avec un index pré-calculé. Car un beau filtre qui ralentit reste un mauvais filtre. Et puis ils ont construit une interface pratique au-dessus du noyau rapide : des échantillons, des chips, une superposition mobile, un bouton de téléchargement. Et ils l'ont connecté en un système unique, où chaque élément connaît tous les autres.
Si vous consultez actuellement votre boutique WooCommerce et voyez des listes déroulantes standard dans les filtres, une pagination numérotée au bas du catalogue et des recharges de page à chaque clic, pensez au nombre de clients que vous perdez chaque jour. Pas à cause des prix, pas à cause de l'assortiment, mais parce qu'il leur est tout simplement gênant de chercher. Le module de filtrage AJAX de COS WP Woo résout ce problème de manière globale : filtrage, affichage visuel, chargement, adaptation mobile, indexation et analyse - le tout dans un seul plugin, sans avoir besoin d'acheter et de configurer cinq solutions différentes. Essayez-le et regardez vos métriques dans une semaine. Je suis sûr que les chiffres vous surprendront.
Et maintenant – une conversation honnête sur les pièges. Parce que je n’aime pas les articles dans lesquels tout est parfait et sans un seul inconvénient. Toute technologie a ses limites et le filtrage AJAX ne fait pas exception.
Le premier écueil est la mise en cache au niveau du serveur. Si vous disposez d'un cache LiteSpeed, Varnish, nginx FastCGI ou de tout autre cache de serveur, les requêtes de filtrage AJAX doivent le contourner. Cela semble simple, mais en pratique, cela nécessite une configuration appropriée. Les requêtes AJAX sont envoyées au même wp-admin/admin-ajax.php ou à un point de terminaison REST personnalisé, et le cache du serveur peut commencer à mettre en cache les résultats du filtrage. En conséquence, l'acheteur sélectionne "Shell" - mais voit les résultats pour Lukoil, car le cache renvoie la réponse à la demande précédente d'un autre acheteur. Nous résolvons ce problème de deux manières : premièrement, nous utilisons les requêtes POST pour le filtrage (les caches du serveur ne mettent généralement pas en cache le POST), et deuxièmement, nous ajoutons des en-têtes sans cache aux réponses. Mais si vous configurez vous-même la mise en cache du serveur, gardez cela à l’esprit, car un filtre AJAX mis en cache n’est pas seulement un bug, c’est un bug qui montre les résultats de quelqu’un d’autre à l’acheteur.
La deuxième pierre est l'accessibilité. Lorsque tout le contenu est mis à jour via JavaScript sans recharger la page, les lecteurs d'écran et autres technologies d'assistance peuvent ne pas remarquer le changement. Nous ajoutons des attributs ARIA à la zone de produit (aria-live="polite") et annonçons les modifications apportées aux technologies d'assistance à chaque mise à jour. Ceci n’est pas perceptible pour le consommateur moyen, mais est essentiel pour les personnes utilisant des lecteurs d’écran. Et cela affecte d’ailleurs le score d’accessibilité de Lighthouse, qui devient de plus en plus un facteur de classement.
Le troisième point concerne les catalogues lourds avec des champs personnalisés. Si vos produits n'utilisent pas d'attributs WooCommerce standards, mais des champs personnalisés (ACF, notre module CF ou simplement wp_postmeta), l'indexation de ces champs nécessite une configuration supplémentaire. Les attributs WooCommerce standard (pa_color, pa_size, etc.) sont indexés automatiquement, mais les champs méta personnalisés doivent être explicitement spécifiés dans les paramètres de filtre - quel champ indexer et comment l'afficher. Nous avons rendu l'interface aussi simple que possible : sélectionnez la clé méta dans la liste déroulante, spécifiez le type d'affichage (case à cocher, curseur, échantillon) - et le système inclut ce champ dans l'index lors de la prochaine reconstruction. Mais vous devez le savoir à l'avance pour ne pas être surpris de savoir pourquoi le nouveau filtre « Pour Point » n'affiche pas de valeur - parce que vous avez oublié de l'inclure dans l'index.
Et la dernière chose est la performance avec un très grand nombre de filtres simultanés. Notre index fonctionne très bien avec cinq à dix filtres actifs simultanément, mais si vous disposez d'un catalogue avec trente attributs et que l'acheteur a activé vingt filtres en même temps, le temps de réponse peut augmenter jusqu'à cent à cent cinquante millisecondes. Cela reste très rapide par rapport au WooCommerce standard (où une telle requête prendrait cinq à dix secondes), mais nettement plus lent que cinquante millisecondes pour un simple filtrage. Dans la pratique, de telles situations se produisent rarement - les acheteurs utilisent généralement trois à cinq filtres à la fois - mais si vous disposez d'un catalogue spécifique avec de nombreuses caractéristiques techniques, cela vaut la peine d'en tenir compte lors de la conception de l'interface. Vous pouvez, par exemple, diviser les filtres en « principal » (visible immédiatement) et « supplémentaire » (ouvert en cliquant) pour réduire la probabilité d'utiliser vingt paramètres en même temps.