Avant toute chose, je ne suis pas un développeur web. Dans mon parcours en informatique j'ai toujours essayé de rester aussi loin que possible de Node.js. Aujourd'hui je compte publier plus de posts sur ce blog, et j'espère que je le ferai si je prends le temps de le faire et de faire des choses qui valent la peine d'être partagées. Ce post décrit une découverte de Next.js et l'environnement Node (et c'est décevant).
Comme cela arrive une fois de temps en temps, je me disais que la façon dont mon blog était fait n'était pas satisfaisante. En effet, j'ai d'abord privilégié une solution faite maison pour générer de l'HTML à partir de fichiers Markdown, puis j'ai changé pour Zola, un générateur de site statique, dans l'espoir d'améliorer le processus. Mais voilà, j'avais le sentiment que Zola me forçait à faire des choses que je n'avais pas envie de faire, et donc je devais toujours avoir des hacks pour faire ce que je voulais. Alors quelle technologie dois-je utiliser pour mon nouveau blog ? Surement réinventer la roue et faire ma propre solution en Python est une bonne idée. Et si j'ai un jour besoin que le blog ne soit pas statique uniquement, je peux ajouter une couche de Flask par dessus. Non, prenons cela comme une opportunité pour essayer les technologies web modernes. D'après internet, les offres d'emplois et les réseaux sociaux (je suis bien informé) le vrai developpeur web doit utiliser des technologies modernes comme React, Vue.js, Svelte, ou que sais-je. Mais le vrai cool kid doit utiliser Next.js, a priori il n'y aucun débat à ce sujet. En effet, beaucoup de grosses sociétés renommées l'utilisent, comme on peut le voir sur leur site vitrine : https://nextjs.org/showcase.
Si vous ne connaissez pas, Next.js est un framework React qui facilite le développement d'applications web. Certains de ses arguments de vente sont la vitesse, l'évolutivité, l'intégration de bonnes pratiques SEO, le rendu server site (Server Side Rendering - SSR) ou la génération de site statique (Static Site Generation - SSG).
Premières impressions
Après quelques heures de développement et de lecture de documentation et de recherche d'erreurs cryptiques, la génération de mon blog était réécrite proprement. Concernant le processus de développement, il faut avouer que les composants React permettent de facilement réutiliser du code dans le projet. Biensûr j'utilise TailwindCSS pour styliser mon site car c'est ce que les personnes à jour font, pas de questions là-dessus, et de façon similaire à React, celà simplifie les combats avec CSS. Si on utilise seulement les classes CSS exposées (et qu'on a une compréhension de CSS biensûr) il semble difficile de se tirer une balle dans le pied, augmentant la vitesse de développement. Mettons tout celà dans un projet Next.js et j'ai maintenant un blog que je peux servir derrière un serveur Next.js ou simplement exporter en tant que site statique. Cependant, puisque je suis plus un développeur "bas niveau", je me demandais quel était l'impact de ces technologies sur la taille et la vitesse des sites. Puisque tout le monde l'utilise, cela doit être correct, non ? Non ? (Meme de Anakin et Padme) Alors que je n'avais pas de JavaScript sur mon blog précédent, maintenant vous pourrez télécharger des centaines de Ko de JavaScript.
Google PageSpeed Insights
Pour mesurer l'efficacité de mon nouveau site, je vais utiliser https://pagespeed.web.dev/ de Google qui permet de parcourir mon site et fournir des informations au sujet du rendu. Voici le premier résultat que j'ai eu :
Résultats de PageSpeed pour la version initiale de ce blog
Avec ce conseil inclus :
Avoid serving legacy JavaScript to modern browsers (Est savings of 12 KiB) Polyfills and transforms enable legacy browsers to use new JavaScript features. However, many aren't necessary for modern browsers. Consider modifying your JavaScript build process to not transpile Baseline features, unless you know you must support legacy browsers. Learn why most sites can deploy ES6+ code without transpiling ------ Évitez de server du contenu JavaScript legacy pour les navigateurs modernes (Estimation de 12Ko sauvés) ...
Si j'ai bien compris, Next.js fourni une façon pour les vieux navigateurs de supporter les nouvelles APIs. Mais apparemment, alors qu'il devrait seulement le fournir pour les vieux navigateurs, il semble que même un navigateur moderne télécharge ce JS inutile. Je n'ai pas creusé le sujet plus que ça.
Mais attendez une minutes, quel est le résultat d'un site Next.js standard sur PageSpeed ? Regardons le site officiel de Next.js, et celui de la société qui le développe, Vercel :
Résultats de PageSpeed pour vercel.com
Résultats de PageSpeed pour nextjs.org
Vous pouvez regarder les résultats vous même :
- https://pagespeed.web.dev/analysis/https-nextjs-org/16zo3xdaa4?form_factor=mobile
- https://pagespeed.web.dev/analysis/https-vercel-com/u748nusk00?form_factor=mobile
Sincèrement, je trouve ça hilarant. J'aurais voulu vérifier celà avant de changer mon blog vers Netx.js, bien que nextjs.org a un meilleur "Speed Index" que moi et je n'ai aucune idée de pourquoi.
Et pour être tout à fait honnête, les résultats sont probablement mauvais à cause du premier chargement. Une fois tous le JS téléchargé (et mis en cache), l'entièreté du site devrait être bien plus rapide. Mais quand même, ça heurte mon petit coeur. Mais si vous avez des conseils ou connaissances à m'apporter sur ce sujet, n'hésitez pas à m'éduquer, ce sera apprécié !
Next.js, est-ce si bien ?
Problèmes de cache aléatoires
Next.js est fourni avec un serveur de développement qu'on peut lancer avec la commande npm run dev
. C'est plutôt cool parceque cela permet d'injecter un script de "hot-reload" (rechargement à la volée ?) dans vos pages, ainsi qu'afficher les stack traces server et client dans le navigateur, rendant le développement plus simple. Mais parfois une erreur incohérente qui ne fait pas sens avec les changements courants va apparaître à l'écran. Redémarrer le serveur corrige le soucis. Vous pourriez passer des heures à essayer de comprendre le bug jusqu'à ce que vous réalisiez que c'est juste un problème de cache stupide. Pas si bien.
Enfer de debugging
Ce n'est pas uniquement propre à Next.js, plutôt à l'entiereté de l'écosystème Node.js je pense, mais j'estime qu'environ la moitié du temps, les stack traces sont inutiles à cause du bundling JavaScript. Vous verrez des stacktraces pleines de JavaScript compressé qui ne sont pas utiles puisque tous les noms de variables et fonctions sont incompréhensibles. Cela m'est arrivé avec le serveur de développement et je n'ai pas trouvé le moyen d'avoir une stacktrace propre, j'ai juste annulé mes changements jusqu'à ce que ça fonctionne à nouveau.
Enfer de dépendances (1)
Évidemment au lancement d'un projet Next.js l'utilitaire nous demande si l'on veut utiliser TypeScript plutôt que JavaScript, et en tant que personne saine d'esprit biensûr que j'accepte, car le typage c'est bien. Mais tôt ou tard, vous devrez vous battre avec le compilateur. Mais le pire type de combat, c'est quand vos dépendances ne sont pas écrites en TypeScript et rendent le compilateur mécontent. Voici un exemple où j'essaie d'utiliser le module negotiator
, mais il n'a pas de définitions de type :
Type error: Could not find a declaration file for module 'negotiator'. '/work/xark.es/node_modules/negotiator/index.js' implicitly has an 'any' type. Try `npm i --save-dev @types/negotiator` if it exists or add a new declaration (.d.ts) file containing `declare module 'negotiator';` 1 | import { match } from '@formatjs/intl-localematcher' > 2 | import Negotiator from 'negotiator' | ^
Alors quoi, dois-je lire le code et deviner le type moi même, ajouter un cast explicite vers any
? Dois-je dégager TypeScript et remplacer tout mon code en JavaScript à nouveau ? Surement rien de tout ça, je vais simplement ajouter un commentaire // @ts-ignore
au dessus de la ligne, de la même façon que j'ajouterais un unsafe {}
à mon code Rust, et tout le monde est content.
Enfer de dépendances (2)
Si vous ajouter une dépendance à votre projet qui dépend d'une version différente de React que votre version courante de Next.js, j'ai remarqué que plusieurs choses peuvent mal se passer.
- Vous n'aurez pas d'avertissement à ce propos (je n'ai jamais eu aucun warning de la part de npm m'indiquant que les versions ne correspondent pas)
- Il pourrait fournir l'entièreté du module obsolète (ici React), ajoutant un bundle de 1Mo pour votre dépendance de 200 lignes de code (je ne sais pas si c'est un problème général, ou un problème avec ce package en lui-même)
- Vous aurez surement des erreurs au runtime
Finalement, j'ai pu tout corriger. Évidemment que les technologies web modernes à la pointe ne ratent jamais de nous décevoir et nous accueillir avec un NaN
quelque part. État de l'art.
Le résultat
Est-ce que je regrette d'avoir passé mon blog à Next.js ? Oui car maintenant il est bloated, gonflé, lourd, et je déteste ça. Non car j'ai appris des choses en le faisant, et j'ai quand même pu réaliser mon objectif initial d'avoir un meilleur contrôle sur mon blog. Donc j'ai :
- Appris plus à propos de l'environnement Node.js
- Appris comment utiliser React et comment cela aide le développement front
- Appris à utiliser TailwindCSS
- Appris à déployer une application Node.js (bien que les cool kids ne font pas vraiment ça, ils poussent juste leur code vers un fournisseur comme Vercel et laissent la magie opérer)
- Perdu les limitations de mon blog précédent
- Téléchargé presque 300 modules Node pour... générer un site web statique (
du -h node_modules | tail -n1
returns403M node_modules
) - Ajouté quelques centaines de Ko de JavaScript plus ou moins utile à mon site (principalement inutile si vous voulez mon opinion)
- Gagné la possibilité de pouvoir tenir une conversation sur les technologies web avec les cool kids
Je ne suis pas déçu de ce voyage, même si je suis toujours fondamentalement convaincu que le web est vraiment n'importe quoi. Biensûr qu'il y a des compromis à faire entre la facilité de développement et les performances, mais il me semble que ce dernier a vraiment été négligé.