- Jampack est un outil de post-traitement qui prend la sortie d’un Static Site Generator et optimise l’expérience utilisateur ainsi que les scores Core Web Vitals ; ce n’est ni un bundler ni un framework
- Il transforme les éléments HTML
<img> et <picture> en images responsives, et ajoute automatiquement des formats comme WebP et AVIF, srcset, sizes, width, height, loading="lazy", decoding="async", etc.
- Les images servies par CDN peuvent être rendues responsives via un
srcset basé sur des paramètres d’URL, et les images externes peuvent être téléchargées sous _jampack puis remplacées par des images locales optimisées
- Les ressources above-the-fold sont traitées avec une priorité élevée, les petites images sont intégrées inline dans le HTML, et les images et iframes below-the-fold sont chargées paresseusement
- Il s’applique en exécutant
npx @divriots/jampack./dist sur le dossier de build du site statique, et effectue lors d’une seconde passe la compression des CSS, JS, HTML, SVG et images
Le rôle de Jampack
- Jampack optimise les sites web statiques en prenant en entrée la sortie générée par un Static Site Generator, ou SSG
- Son objectif est d’améliorer l’expérience utilisateur et les scores Core Web Vitals
- Le README précise que Jampack n’est « ni un bundler ni un framework »
- L’article de présentation est disponible ici : Read the introduction blog post
Optimisation des images
- Les éléments
<img> classiques sont convertis en images responsives
- Pour le
src d’origine, un fichier WebP est créé et un srcset est ajouté
- Des attributs comme
sizes="100vw", loading="lazy", decoding="async", width et height sont ajoutés
- Les éléments
<picture> sont transformés en structures responsives incluant plusieurs formats d’image
- Un élément
<source type="image/avif"> est ajouté pour AVIF
- Un élément
<source type="image/webp"> est ajouté pour WebP
- L’élément
<img> d’origine reçoit également srcset, sizes, loading, decoding, width et height
- La fonctionnalité d’optimisation des images renvoie vers la documentation
optimize-images, mais le lien correspondant dans le README est un chemin relatif
Gestion des images CDN et externes
- Les images CDN peuvent conserver leur URL distante tout en recevant un
srcset responsive
- L’exemple crée plusieurs candidats de largeurs différentes en ajoutant les paramètres
w, fit=min et auto=format à une URL d’image Unsplash
- L’image d’origine reçoit aussi
loading="lazy", decoding="async" et sizes="100vw"
- Les images externes peuvent être téléchargées puis remplacées par des fichiers locaux optimisés
- L’exemple remplace une image Unsplash externe par un chemin comme
_jampack/ab99b9d280ce4cf7cfc810b59f3a7739.jpg.webp
- L’image convertie inclut
width, height, srcset, sizes, loading et decoding
Optimisation above-the-fold, CSS et liens
- Jampack optimise séparément les ressources above-the-fold
- Les images sont chargées avec une priorité plus élevée
- Les petites images sont embarquées dans le HTML
- Les ressources below-the-fold sont chargées paresseusement
- Les images et les iframes sont concernées par le lazy loading
- Le Critical CSS est intégré inline dans le HTML
- L’objectif est d’éviter le FOUC susceptible de se produire pendant le téléchargement et le parsing des feuilles de style
- Le reste du CSS est chargé paresseusement
- Le préchargement des liens vise à accélérer les futures navigations entre pages
- quicklink peut être utilisé pour le gérer dynamiquement lorsqu’un lien entre dans le viewport
Compression des ressources et mode d’exécution
- Lors d’une seconde passe, Jampack compresse toutes les ressources qui n’ont pas été modifiées, en conservant le même nom et le même format
- Les outils de compression par extension sont les suivants
- Lorsque le site web statique se trouve dans le dossier
dist, exécutez la commande suivante
npx @divriots/jampack ./dist
- Les options supplémentaires sont disponibles dans CLI options
Cas d’usage et signification du nom
1 commentaires
Avis sur Hacker News
C’est exactement l’outil que je cherchais. J’écrivais moi-même des scripts basés sur Sharp pour faire ce genre d’optimisation d’images, mais Jampack le remplace complètement et fonctionne bien mieux.
Après avoir généré un site statique Quarto puis lancé Jampack, la taille du dossier a diminué de 32 %, et je n’ai pas encore constaté d’inconvénient notable.
D’après PageSpeed Insights, avant Jampack, le mobile obtenait 52 en performance, 73 en accessibilité, 100 en bonnes pratiques et 85 en SEO ; le desktop obtenait 90 en performance, 75 en accessibilité, 100 en bonnes pratiques et 82 en SEO.
Après application, les scores sont passés à 49 en performance mobile, 80 en accessibilité, 100 en bonnes pratiques, 92 en SEO ; et côté desktop à 85 en performance, 82 en accessibilité, 100 en bonnes pratiques, 91 en SEO.
Il existe aussi une ressource indiquant que « la médiane de 5 exécutions Lighthouse est deux fois plus stable qu’une seule exécution » : https://developers.google.com/web/tools/lighthouse/variabili...
georges [at] divriots [dot] com
Ça me rappelle le module PageSpeed pour Apache et Nginx : https://developers.google.com/speed/pagespeed/module
Le dépôt GitHub est également archivé : https://github.com/apache/incubator-pagespeed-ngx
Est-ce qu’il a été déplacé ailleurs ?
Waouh, ça me plaît pas mal. Je compte l’essayer.
Si quelqu’un trouve ça mauvais, j’aimerais qu’il pointe les défauts. À mes yeux, ça ressemble à la compilation de C en assembleur ultra-optimisé, et à un outil qui fait clairement à ma place quelque chose que je n’ai pas envie de faire moi-même.
Je pense qu’en écrivant le HTML et le CSS les plus simples et intuitifs possible, les navigateurs sur tous les appareils devraient simplement les rendre correctement.
Si l’on doit vraiment déployer des artefacts optimisés à ce point, autant sauter complètement HTML et CSS, déployer du WebAssembly très optimisé et laisser les développeurs utiliser le langage qu’ils veulent.
Ce serait bien d’avoir une méthode pour sous-ensemble les polices selon les plages Unicode de la sortie du SSG, et pour figer les axes OpenType à partir des
font-feature-settingsdéfinis dans le CSS.Je me demande si c’est ce que tu entends par « figer les axes OpenType à partir des font-feature-settings », ou si tu parles d’autre chose.
J’aimerais aussi optimiser le sous-ensemble des polices, mais je ne sais pas encore vraiment quelle marge d’amélioration cela donnerait. Je me demande si tu l’as déjà fait manuellement.
Le concept consistant à identifier le CSS critique qui devrait être inline plutôt que dans une feuille de style séparée est intéressant.
J’espérais qu’il existe une méthode de principe pour distinguer le CSS critique du non critique. Par exemple, considérer que les effets d’interaction utilisateur comme
:hoversont toujours non critiques.Mais la bibliothèque utilisée rend la page puis fait sa meilleure estimation des règles pouvant être considérées comme critiques, ce qui est un peu décevant : https://github.com/GoogleChromeLabs/critters
Bien sûr, si vous inlinez aussi les polices, je peux comprendre ; mais si les styles seuls dépassent 50 Ko, c’est généralement une mauvaise direction.
Plus sérieusement, l’inlining est extrêmement bon pour les performances, même comparé à un cache chaud, et le seuil à partir duquel une feuille de style ou un script externe devient préférable est plus élevé qu’on ne l’imagine, parfois jusqu’à plusieurs centaines de Ko selon les standards courants du marché.
Le concept de CSS critique me donne l’impression d’une approche défaitiste qui tente de récupérer un peu de performance gaspillée plutôt que de corriger le problème de fond.
Cela dit, ce jugement ne repose pas sur une méthode systématique, mais sur une expérience légère et des observations. J’aimerais que quelqu’un mesure ce concept plus correctement, mais je doute que ce soit moi qui le fasse.
On dirait que ça couvre plusieurs des usages pour lesquels les gens choisissent au départ un SSG et des plugins, surtout dans le cas d’Astro ou d’Eleventy.
Y a-t-il une raison de préférer en faire une étape séparée après le build ? Les rebuilds en développement seraient plus rapides, mais cela ressemble à un compromis avec le risque de passer à côté de bugs subtils introduits, par exemple, en ajoutant des déclarations de largeur d’image.
Pour quelqu’un qui déteste travailler sur la mise en page web et refuse même de l’apprendre, mais doit parfois s’y coller, cet outil a l’air excellent.
Ça a l’air bien. Personnellement, toutefois, je n’aime pas devoir attendre les images quand je fais défiler la page sous la ligne de flottaison.
Par défaut, une fois le contenu visible initialement terminé, le reste du contenu plus bas est-il chargé en arrière-plan ?
loading="lazy"comme « ne chargez pas cette image/iframe tant qu’elle n’est pas presque visible » : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/im...En revanche, le ratio d’aspect est ajouté inline, donc la mise en page ne change pas une fois le chargement terminé. Cela évite le plus grand péché du lazy loading.
loading="lazy"natif du navigateur.Pour l’instant, il n’existe pas de moyen de modifier ce comportement, mais on pourrait ajouter une option pour précharger en arrière-plan les images sous la ligne de flottaison une fois toute la page chargée. C’est une très bonne idée.
Je crains toutefois de charger aussi des images inutiles en bas de page. Si c’est une option, chacun pourra l’activer ou la désactiver, donc ça devrait aller.
Quels générateurs de sites statiques sont utilisés en production ? Cet outil pourrait probablement optimiser davantage leur sortie.
Par exemple, hier j’ai passé toute la journée à suivre des exemples pour convertir un site React Divjoy en HTML simple afin de le servir depuis un bucket S3. Je ne pensais pas que ce serait aussi difficile, et je suis encore en train de galérer.
Idéalement, j’aimerais quelque chose qui déploie automatiquement vers un bucket S3 et connecte aussi le domaine. Ça fait mal d’avoir payé, puis de voir le développeur disparaître et le Discord abandonné. C’est pour ça que je préfère toujours davantage le FOSS.
Ils possèdent déjà une partie de ces fonctionnalités, dans une certaine mesure.
Sur l’un de mes projets, ça n’a pas beaucoup changé les choses. Par exemple, la taille totale du bundle a diminué, mais la taille gzip a augmenté, donc en pratique c’était une perte nette pour moi.
Cela dit, les améliorations CSS semblent vraiment avoir aidé.
L’idée paraît excellente, et si le projet avait eu des images, cela aurait probablement été utile.
On peut désactiver cette fonction en définissant browserlist sur une chaîne vide : https://jampack.divriots.com/features/browser-compatibility/