Sept filtres actifs en simultané, quarante mille modules de formation indexés, une exigence de temps de réponse sous 50 millisecondes même sur les combinaisons de filtres les plus rares : le cahier des charges de la recherche front d’une plateforme e-learning headless imposait de configurer les facettes Algolia avec une rigueur que le volume de contenu ne pardonnait pas à l’approximation.
Contrairement à un catalogue de quelques centaines de fiches où presque n’importe quelle configuration de facettes fonctionne correctement, un volume de cette ampleur révèle rapidement les choix de configuration mal calibrés, sous forme de lenteurs perceptibles dès que plusieurs filtres se combinent.
Étape 1 : ne déclarer que les facettes réellement filtrées
Le catalogue comportait une trentaine d’attributs par module (durée, niveau, langue, format, thématique, intervenant, certification, mots-clés). Déclarer l’ensemble de ces attributs comme attributesForFaceting aurait considérablement alourdi la taille de l’index et ralenti chaque requête, sans bénéfice pour l’utilisateur final :
{
"attributesForFaceting": [
"searchable(thematique)",
"niveau",
"langue",
"format",
"certification",
"filterOnly(intervenant_id)",
"duree_tranche"
]
}
Seuls les attributs réellement exposés comme filtres dans l’interface figurent dans cette liste. Le modificateur filterOnly a été appliqué à l’identifiant d’intervenant, filtré uniquement depuis une page de profil formateur, sans jamais afficher de compteur associé sur la page de recherche principale, ce qui évite le calcul inutile de ce compteur sur chaque requête générale.
Étape 2 : découper la durée en tranches plutôt qu’en valeurs exactes

La durée d’un module, exprimée en minutes, variait de 5 à plus de 600 selon les formations. Une facette sur la valeur exacte en minutes aurait généré des milliers de valeurs distinctes, rendant tout affichage de filtre par cases à cocher inexploitable. Un champ calculé duree_tranche a été ajouté à l’indexation, regroupant chaque module dans une tranche prédéfinie :
function calculerTrancheDuree(int $minutes): string {
return match (true) {
$minutes < 15 => 'moins_15_min',
$minutes < 60 => '15_a_60_min',
$minutes < 180 => '1_a_3_heures',
default => 'plus_3_heures',
};
}
Ce champ, calculé une seule fois à l’indexation plutôt qu’à chaque requête de recherche, réduit à quatre le nombre de valeurs distinctes de cette facette, tout en restant suffisamment parlant pour un apprenant qui cherche une formation courte entre deux réunions.
Étape 3 : garder des compteurs cohérents entre facettes
Un piège fréquent avec les facettes Algolia consiste à afficher un compteur par valeur de facette calculé sans tenir compte des autres filtres déjà actifs, ce qui produit des compteurs incohérents (un compteur de 200 modules en langue anglaise alors qu’un filtre de niveau « débutant » déjà actif ne devrait en laisser apparaître que 40). La configuration par défaut d’InstantSearch calcule bien ces compteurs relativement aux autres filtres actifs, à condition que chaque facette figure dans la liste attributesForFaceting et que le composant de filtre utilise les facetFilters plutôt qu’un simple filters textuel non structuré.
Résultat mesuré
| Configuration | Temps de réponse moyen | Sur combinaison rare de 4 filtres |
|---|---|---|
| Toutes facettes déclarées sans filterOnly | 85 ms | 310 ms |
| Facettes réduites + tranches de durée | 22 ms | 48 ms |
Ce que cette configuration ne couvre pas
Cette configuration porte exclusivement sur la structure des facettes et leur performance de filtrage. Le contenu pédagogique des modules eux-mêmes, ainsi que leur organisation en parcours de formation, relève d’un travail éditorial totalement distinct.
Pour aller plus loin
Sur un catalogue de cette taille, chaque facette ajoutée sans discernement a un coût direct sur la performance de recherche perçue. Réduire le périmètre des facettes déclarées au strict nécessaire, et transformer les attributs numériques continus en tranches discrètes, reste la meilleure garantie pour maintenir un temps de réponse constant, quel que soit le nombre de filtres combinés par l’utilisateur.