Omacronides 12 : Googlebot, javascript, indexation et site web statique
Ce site est entièrement piloté par du jascript côté navigateur web depuis deux ans environ. Je suis très satisfait du résultat, en tant que codeur et qu'utilisateur. Mais je viens de me rendre compte que le site a quasiment totalement disparu des moteurs de recherche (oui, je suis long à la détente). Seule la page d'accueil y est encore référencée. Petite rectification du site pour s'assurer donc un meilleur référencement.
Pages disparues des moteurs de recherche
Le référencement du site à totalement disparu depuis le passage en full javascript alors qu'il n'était franchement pas trop mauvais avant ; bon, je ne vérifiais pas ça très souvent mais à chaque fois que je le faisais, j'étais plutôt bien placé. Maintenant, c'est le désert !
Exemple : Une simple recherche "omacronides sandman" ne retourne que la page d'accueil sous Duckduckgo ou Qwant. Dans Google, elle retourne la page d'accueil, la page de tag "sandman" et la page de la série Netflix (j'aurai aimé qu'elle retourne aussi la page de la bédé).
Autre exemple avec la recherche direct du titre "Les réintérprétations de Frisano Omacronides" sur qwant et sur duckduckgo.
Comme je dis : le désert total ! Si Google contient encore quelques pages, les autres ne semblent plus connaître que la page d'accueil.
Javascript et robots d'indexation
Cela fait donc deux ans que le serveur ne fournit plus qu'une seule page web, un index.html sur lequel s'appuie le javascript pour construire la page demandée. Donc, sans javascript, toutes les pages du site se ressemblent : une page presque vide.
Si vous consultez le site depuis un navigateur web relativement moderne (pas plus de cinq ans), cela ne pose pas de problème. Mais si vous êtes un robot d'indexation, les outils utilisés par les moteurs de recherche pour indexer les pages web, c'est une autre affaire...
- Première étape : le robot passe une première fois et ne récupère que le html, sans exécuter le javascript, puis il met la page en file d'attente de rendu.
- Seconde étape : le moteur de rendu exécute la page dans un navigateur headless (Chrome) afin d'obtenir le « html complet », après exécution du javascript.
Ce n'est donc qu'avec cette seconde étape que la page ressemble à ce qu'elle doit être, mais le traitement n'est pas trivial : il demande plus de ressource, peut ne pas être exécuté et n'arrive pas forcément à rendre correctement la page (googlebot utilisait une version assez ancienne de Chrome pour cette phase de rendu avant de se calquer sur les sorties).
Bref, l'indexation des sites entièrement en javascript n'est pas encore totalement au point, surtout que les autres moteurs de recherches ne semblent pas vraiment pratiquer cette phase de rendu...
Revenir à des pages HTML côté serveur ?
Le constat s'impose donc : pour avoir une indexation à peu près correcte, du moins pas fortement handicapée, il faut absolument que le html signifiant soit renvoyé par le serveur.
D'accord mais je ne souhaite pas vraiment revenir en arrière avec une usine à gaz / CMS PHP (ou python ou autre). Comment faire ?
Partir du principe que le code javascript qui construit la page web côté navigateur pourrait parfaitement — avec quelques adaptations — la construire côté serveur. Cependant, mon hébergeur (OVH) n'autorisant pas (encore ?) nodejs sur les hébergements mutualisés, cette construction ne peut pas être dynamique (à la demande) ; il faut donc que cela soit des pages statiques.
Oui mais ces pages statiques ne doivent être là que comme une sorte de backup : dés que l'utilisateur click quelque part sur la page, il doit revenir sur la forme dynamique, côté navigateur, du site.
Génération de site sous node.js
Ce qui est agréable et rassurant, c'est qu'en quelques heures et une centaine de lignes de code, l'architecture mise en place à pu devenir un générateur de site statique. Et le code existant n'a nécessité que quelques adaptations à la marge, surtout pour lui permettre de tourner sous nodejs.
Première version : 2000 pages html construites en 30 s.
Content mais ça me parait bien trop long.
L'algo ne peut pas totalement se comparer aux performances de vrais générateur de site statiques comme Jekyll, Hugo & co mais le code fait parfaitement le boulot et il n'y a pas à rougir : pour un outil codé en quelques heures à partir d'un code qui n'est pas pensé — à la base — pour générer des fichiers html mais pour créer des nœuds DOM et une interface graphique de site web, 2000 pages en 30s, ca peut se comparer.
Il y aurait de la grosse optimisation à faire en créant une voie alternative pour la génération, jouant avec des templates et de la concaténation de strings. Pour l'instant, on passe toujours par la voie de génération d'une arborescence DOM chargée d'afficher la page dans la navigateur ; ce n'est qu'à la fin qu'elle est détournée pour être sérialisée sous forme de chaîne de caractères.
Mais ce n'est pas ma préoccupation majeure vu que je ne compte pas générer les 2000 pages tous les jours. L'important c'est que le truc marche.
Une page statique qui bascule en full javascript
Seules les pages de contenus, notes, articles, œuvres et projets, sont générées en pages HTML ; Ce sont finalement les seules qui nécessitent une indexation par les moteurs de recherche. Les pages d'index et de taxonomies (catégories, mots-clés, dates) restent toujours générées côté navigateur.
- Si vous arrivez directement sur une page de ressource, c'est la page statique qui sera servie par le serveur.
- Si vous passez par un autre point du site ou dés que vous cliquez sur un lien menant vers une autre page du site, vous basculez en mode full javascript.
Le truc propre aussi, c'est que si la page html est absente, la version javascript prend le relais.
Génération au déploiement
Le processus de génération est intégré à celui de build/déploiement :
- Si le fichier markdown d'un contenu est modifié, le prochain build avant publication régénèrera la page html correspondante.
- Si la structure de la page principale (et unique) `index.html` est modifiée, toutes les pages web sont regénérées.
Comme j'utilise rsync pour déployer sur le serveur distant, seuls les fichiers modifiés par rapport à l'upload précédent seront transférés.
Aiguillage au niveau du serveur apache
J'avais jusque là une config apache des plus simple : tout ce qui n'est pas fichier (image, javascript, feuille de styles, etc.) était redirigé vers un unique point d'entrée : la page index.html. Avec la nouvelle mouture, on dois s'assurer que certaines requêtes soient redirigées vers les pages statiques tandis que les autres poursuivent leur chemin.
Le plus embêtant est que je dois maintenant y mettre de l'information précise liée à la structure des urls ; avant, les règles existantes étaient générique et pouvaient s'appliquer à tous site :
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/not-found$
RewriteRule . /index.html [L]
Bugs à corriger / évolution à apporter
- Certains composants web comme la table des matières ne se comportent pas correctement dans la version statique.
- Il faut aussi que le moindre click sur une page statique fasse revenir sur la version dynamique.
La prochaine étape sera sans doute de détacher la structure propre à ce site pour définitivement en faire un outil de publication/génération de site web. Toutes les briques sont là ; y a plus qu'à !
Débug des rewrite apache
Activer les logs :
LogLevel alert rewrite:trace8
Éviter de faire ca en prod et désactiver les logs dés que le dev est fini parce qu'ils impactent beaucoup les performances du serveur.
Composants web utilisables dans des pages statiques
À écrire...