La stack de ce site
J’ai hésité assez longtemps pour décider du meilleur outil pour publier ce site internet ; il me fallait à la fois un moteur de blog qui mette l’accent sur la performance et qui soit suffisamment évolutif pour pouvoir me permettre de rajouter facilement du contenu personnalisé et éditer la mise en page.
Mes besoins
Mes attentes lors de la création de ce blog était de pouvoir disposer d'un site me permettant à la fois de publier des brèves au quotidien (type Shaarli, des articles de longueur plus conséquentes et de mettre en ligne mes carnets qui me servent principalement à garder une trace de sujet plus ou moins techniques dans lesquels je me suis plongé.
Le point commun de ces modes de publication devait être d'avoir un site qui mette l'accent sur l’accessibilité des utilisateurs à travers 3 axes :
- le suivi des bonnes pratiques de l'accessibilité du web
- des performances les plus élevées possible, en limitant au maximum le poids des éléments chargés sur chaque pages
- pas de nécessité d'avoir javascript activé pour consulter le site
Benchmark en 5 minutes
Après un rapide tour des moteurs de blog disponible je me suis arrêté à la liste (non-exhaustive) suivante :
Wordpress (PHP, MySQL)
- v Installation simple
- v Création de posts simple et complète
- v Fonction de recherche
- v Facile de créer des pages
- v Des thèmes et des plugins à foison…
- v … mais à la qualité et à la maintenance variables
- v la customisation devient rapidement très complexe
- v 20 requêtes, 230 Ko / Charge en 1.5s / DOMContent en 1s
Ghost (NodeJS, MySQL)
- v Installation facile
- v Design modern et minimaliste
- v Intègre la recherche
- v Création de posts simple et complète
- v 40 requêtes, 4.4 Mo / Chargement en 1.5s / DOMContent en 160ms
Hugo (Markdown)
- v Extrêmement performant
- v Pas de base donnée
- v Pas de fonction de recherche
- v 4 requêtes, 14.29 Ko / Chargement en 0.3s / DOMContent en 260ms
J'ai déjà eu à utiliser et à migrer des sites Wordpress par le passé et mes souvenirs en restent douloureux. L'utilisation basique d'un site Wordpress est à porter du quidam moyen, mais la création d'un thème et de manière plus générale la customisation reste un calvaire si l'on veut faire ça de manière propre en assurant la compatibilité et maintenance avec les mises à jour futures.
J'ai essayé Ghost pendant quelques jours et bien que le code applicatif soit beaucoup plus claire et organisé que celui de Wordpress, je suis arrivé à la conclusion que ce type d'outils offrait trop de possibilités et de complexité par rapport à mes besoins.
Hugo me paraissait très attractif sur la partie performance et simplicité, mais la création d'un article passait nécessairement par le fait d'avoir un terminal sous la main (ou coupler le tout à un process de continuous deployment et à un repository sur github / gitlab / bitbucket). Cependant, quitte à suivre cette voie, il me paraissait plus facile de produire mon propre moteur de blog de manière à n'avoir à disposition que des fonctionnalités nécessaire à mes besoins.
Créer un moteur personnalisé ?
Ayant devant moi quelques jours d'intercontrat j'ai décidé que, en plus de me permettre de remettre les mains dans le cambouis des technologies web, développer ma propre solution répondrait à la totalité de mes besoins tout en me permettant d'avoir une vision complète sur mon outil.
Je me suis donc lancé dans le développement d'une solution en partant sur les technologies suivantes :
- NodeJS: On ne le présente plus, NodeJS est un environnement serveur utilisant javascript
- ExpressJS: Simple d'utilisation et relativement minimaliste, ExpressJS est un framework back-end pour NodeJS permettant notamment de gérer le routing du site ainsi que le chargement des assets statiques (html, css, images)
- SQLite: SQLite est un moteur de base de donnée SQL qui offre entre autres l'avantage de ne pas nécessité d'être hébergé en parallèle et d'être contenu dans un simple fichier. Cela permet notamment de faire des backups et de redéployer l'intégralité du site aisément sans avoir à configurer une base MySQL
- Pug: Pug est un moteur de template qui permet de gérer très facilement le rendu côté serveur et donc de se passer d'API et de rendu côté client
Première itération
Il m'a fallu un peu plus de 4 jours pour obtenir un résultat satisfaisant. Tout n'était pas parfait (pas de support multi-utilisateur, pas de statistiques de consultation, pas de fonction de recherche) mais les fonctionnalités dont j'avais besoin étaient là, notamment:
- v création et édition d'articles, public ou privé, écrit en Markdown et restranscrit en html, permettant notamment d'afficher du code avec coloration syntaxique
- v création de liens, avec récupération automatisée de miniature youtube/dailymotion
- v pagination
- v upload et gestion de fichiers (images, vidéos, audios)
- v pas de javascript sur la partie front
- v pas de police de caractères importée
- v 30 ko, 3 requêtes / Chargement en 100ms / DOMContent en 80ms
Le code source de cette version faisait moins 100Ko et aurait demandé peu de travail avant d'être publiable sur Github.
Limitations et seconde itération
Après quelques semaines d'utilisation et la publication de plusieurs carnets il m'est vite apparu que si les différentes pages du site étaient relativement légère, le temps de réponse du serveur pour certaines d'entre elles était assez élevé (dû au temps de transformation du markdown en html à la volée) ; allant parfois jusqu'à près d'une demi-seconde.
En outre, certaines pages d'article ou de carnet nécessitant l'utilisation de highlight.js et Katex, les styles CSS permettant d'utiliser ces éléments étaient chargés sur toutes les pages de cette catégorie.
Suite à ces considérations J'ai donc décidé d'effectuer une seconde itération en repartant de zéro concernant la partie code du site avec la logique suivante : les différentes pages et articles sont intégralements écrit en markdown et leur contenu injecté dans des templates html via une étape de build.
Les avantage principaux d'avoir une étape de build sont les suivants :
- v contrairement à un site "html-only" le code est facilement maintenable ; il suffit de modifier un fichier de template html pour mettre à jour l'ensemble des pages l'utilisant
- v il n'y a pas de base donnée, tout est contenu dans des fichiers markdown dont le contenu peut être facilement recherché et modifié
- v le résultat du build étant un ensemble de fichier html statiques ceux-ci peuvent directement être mis à disposition via nginx sans avoir à mettre en place un serveur node, python ou autre. De fait les performances sont également meilleures qu'auparavant et le site peut être redéployé sur un nouveau serveur ou chez un nouvel hébergeur en quelques secondes
- v enfin et de manière plus générale (et c'est le point le plus important), le tout demande peu de maintenance côté serveur. Pas de question de mise en cache, de maintenance de db, de mise à jour de package. La surface des risques de sécurité est donc grandement réduite
Le seul inconvénient que je vois aujourd'hui est le fait que tout comme Hugo l'ajout de nouveaux articles ou brèves n'est pas instantané mais demande de manuellement ajouter un fichier markdown et de refaire un build du site avant de le redéployer. J'utilise pour le moment Github actions pour effectuer ces étapes lors de la mise à jour du repository du site.