Une recherche instantanée sur WordPress

Dans ma quête d’optimisation de mon blog personnel qui tourne sur WordPress, quête qui alimente régulièrement ce blog technique, la recherche interne est un problème particulièrement complexe. Le blog compte actuellement environ 820 articles pour un total d’un million de mots. Ajoutons à cela les mots-clés et la taxonomie, les commentaires éventuellement et j’atteins vite les limites de mon hébergement mutualisé. D’autant que, pour diverses raisons qui feront peut-être l’objet d’un article séparé, j’ai choisi de remplacer la recherche par défaut par celle fournie par Relevanssi qui indexe plus, mais est plus lente.

recherche-wordpress

Accélérer la recherche sur un blog

Avant d’évoquer cette astuce qui offre une recherche instantanée sur tous les hébergements, un mot sur l’alternative Google. De fait, le moteur de recherche est souvent meilleur que ce que les systèmes de gestion de contenu, comme WordPress, peuvent offrir. Les résultats sont non seulement bien plus rapides, ils sont souvent plus pertinents. Je me refuse toutefois à installer ce système sur mon blog, essentiellement pour des raisons de principe, mais aussi pour des raisons techniques (possibilités limitées en matière d’intégration dans le thème). Il existe aussi d’autres solutions extrêmement performantes, puisqu’elles reposent sur des serveurs externes très rapides, comme Swiftype ou yolink. Malheureusement, elles sont aussi payantes et souvent assez chères et ce blog ne rapporte pas d’argent.

Pour accélérer la recherche, je n’ai eu d’autres solutions jusque-là que le cache. Relevanssi dispose d’une option pour mettre en cache les résultats des requêtes et même si cette option n’est pas recommandée par son concepteur en raison de la place qu’elle peut occuper dans la base de données, elle ne pose aucun problème chez moi. Suivant cette astuce précédemment évoquée, j’ai aussi réussi à mettre en cache les pages de résultats, mais ce n’est efficace que pour les requêtes les plus courantes.

Aucune de ces solutions n’est parfaite. On peut faire confiance à un tiers, mais c’est soit cher, soit offrir à ses utilisateurs une recherche qui ressemble à Google. On peut aussi mettre en cache les résultats, mais le problème de la lenteur reviendra dès qu’un lecteur cherchera autre chose.

Une recherche statique et instantanée

Dans mes problèmes de lenteur, l’hébergement mutualisé est responsable, mais ce serait stupide de lui faire porter complètement le chapeau. Chercher un mot dans une base de données qui en compte plusieurs centaines de millions est long, c’est logique et normal. Pour accélérer l’opération, il faudrait des serveurs très puissants et même plusieurs serveurs qui pourraient se répartir la tâche. Pour un simple blogueur comme moi, c’est impensable.

Pour accélérer la recherche, le plus simple est de réduire le champ lexical et surtout le sortir d’une base de données. Les blogs entièrement statiques, comme ceux créés avec Jekyll ou d’autres moteurs similaires, sont par nature plus rapides, puisqu’ils sont dépourvus de base de données. Quand le serveur n’a plus qu’à lire des fichiers sur son disque dur, ses performances sont améliorées. Et ces systèmes de blogs statiques permettent relativement facilement de mettre en place des recherches très rapides, bien que souvent plus limitées.

Exemple de recherche statique, sur un blog statique. Seul le titre des articles est cherché, mais le résultat apparaît instantanément.
Exemple de recherche, sur un blog statique. Seul le titre des articles est cherché, mais le résultat apparaît instantanément.

C’est justement en découvrant la solution mise en place par César Parent, que j’ai eu l’idée d’une recherche instantanée pour mon blog. Pour obtenir les meilleurs des deux mondes, j’ai mis en place une solution hybride :

  • Une recherche statique basée exclusivement sur les titres des articles affiche instantanément ses résultats dès qu’on tape du texte dans le champ de recherche. Comme les titres seuls sont indexés, elle est moins précise que la recherche habituelle, mais…
  • Si cela ne suffit pas, la recherche de base de WordPress reste accessible en lançant la recherche comme d’habitude. Celle-ci est basée sur les titres, mais aussi le contenu des articles et surtout toute la taxonomie associée : elle permet de trouver plus précisément un article.

Cette solution concilie le meilleur des deux mondes et elle offre une recherche vraiment rapide, disons même instantanée sur un blog de taille de modeste, y compris sur un hébergement mutualisé comme le mien. Vous pouvez l’essayer sur mon blog hébergé par une offre Pro d’OVH, les résultats apparaissent immédiatement. Ayant dépassé les 800 articles, je craignais un peu un chargement ralenti, mais il n’en est rien. La solution n’a pas été testée sur un gros blog et il est probable qu’elle pose rapidement problème.

Voici le résultat, en action : à partir de trois lettres tapées, une liste apparaît instantanément et elle mise à jour au fur et à mesure que la requête est saisie. Si les résultats proposés (10 maximum) ne suffisent pas, le visiteur peut toujours lancer la recherche complète en appuyant sur la touche « Entrée ».

instant-search-wp

Mise en place

Voici rapidement comment mettre en place la même fonction sur votre blog. Rappelons d’abord qu’il faut héberger WordPress sur son propre serveur et que quelques connaissances de base en HTML, CSS ou encore en PHP et JavaScript ne seront pas de trop.

Le principe général est le suivant :

  1. Quand vous publiez un nouvel article, une fonction en PHP est activée pour créer une liste de tous les articles publiés sur côté blog. Cette liste est enregistrée dans le dossier de base de WordPress sous le nom de search.json.
  2. Quand un visiteur tape quelques lettres dans le champ de recherche du blog, un script en JavaScript analyse les lettres tapées et cherche dans la liste générée à l’étape précédente les articles qui correspondent.
  3. Le cas échéant, une liste d’articles s’affiche instantanément sur votre site.
Le fichier search.json créé automatiquement lors de la publication d'un nouvel article.
Le fichier créé automatiquement lors de la publication d’un nouvel article.

Pour générer la liste, une fonction doit être ajoutée dans le fichier functions.php de votre thème. Si vous ne souhaitez pas perdre les modifications, pensez à créer un thème enfant et à faire les modifications proprement. Vous trouverez le contenu de cette fonction à cette adresse.

Comme on l’évoquait précédemment, la fonction n’agit que lors de la publication d’un article et d’un article public uniquement. Avant cela, la recherche instantanée ne sera pas en place, mais vous pouvez tester en publiant un article privé et en commentant les lignes 5 à 8 dans la fonction.

Extrait de la fonction qui indexe tout le contenu du blog.
Extrait de la fonction qui indexe tout le contenu du blog.

Pour que les résultats s’affichent, vous devez télécharger ce fichier JavaScript et le charger dans la page. À vous de voir comment faire, le fichier n’a pas à être dans le dossier de votre thème, mais c’est sûrement le plus simple. Pour ajouter l’appel au script dans le header, suivez la méthode officielle, ou intégrez-le directement au header de votre thème.

Extrait du script JavaScript qui permet d'afficher les résultats d'une recherche.
Extrait du script JavaScript qui permet d’afficher les résultats d’une recherche.

La dernière étape se fait en HTML et en CSS, puisqu’il s’agit d’afficher correctement les résultats. À vous de voir ce que vous voulez faire, j’ai choisi pour ma part une zone de la même taille que le champ de recherche, avec un petit peu de transparence et une mise en avant très nette de l’article que l’on va ouvrir avec une couleur de fond plus sombre au survol de la souris. Seul élément obligatoire, spécifier dans votre thème l’emplacement pour la liste qui affichera les résultats. Le code à ajouter est celui-ci :

<ul id="searchPage" class="search_results"></ul>

Limites et améliorations possibles

Cette recherche instantanée a été imaginée et développée le temps d’une après-midi et elle reste largement perfectible. Voici les principales limites et idées d’améliorations que l’on pourrait envisager…

  • La recherche est limitée aux titres des articles pour des raisons d’optimisation, mais on pourrait très bien ajouter les catégories, les tags ou encore une autre information. Sur 800 articles, on perdrait sans doute le bénéfice de l’instantané.
  • Les résultats s’affichent nécessairement dans l’ordre de publication. Dans mon cas, cela n’a pas tellement d’importance.
  • On doit utiliser la souris pour choisir un résultat dans la liste. L’utilisation du clavier est peut-être envisageable, mais demande sans doute trop de travail pour que cela en vaille la peine.
  • Pour le visiteur, il n’est pas évident que la recherche avancée de WordPress reste disponible en appuyant sur la touche de retour du clavier. Peut-être pourrait-on ajouter un lien après les articles trouvés, vers la page de recherche complète ?
  • Dans l’idéal, le fichier ne devrait pas être généré qu’au moment de publier un nouvel article, mais aussi lorsque l’on change le titre d’un ancien élément.
  • Enfin, cette astuce a fait ses preuves sur un blog de 800 articles, mais elle atteindra ses limites pour ceux qui comptent plusieurs milliers, voire dizaines de milliers d’articles. C’est un problème, mais en même temps de tels volumes exigent des solutions professionnelles adaptées. À propos de performances, notons tout de même que le fichier search.json est systématiquement chargé sur toutes les pages. Si votre blog grossit un peu, c’est un point à surveiller en matière de performances.

Cette astuce ne fonctionnera sûrement pas dans tous les cas, mais elle améliore considérablement la recherche de base de WordPress et méritait ainsi d’être détaillée et partagée. Je remercie César Parent pour sa précieuse aide technique (c’est lui qui a tout fait, en fait) et je vous encourage à le suivre sur son blog ou sur Twitter.

Si vous utilisez la même technique sur votre blog, n’hésitez pas à partager en commentaire votre expérience et vos impressions sur son fonctionnement ! Et en cas de bug, j’essaierai d’assurer un SAV, dans la limite de mes maigres connaissances…

Publicités

Répondre

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s