4 points par GN⁺ 2024-03-26 | 1 commentaires | Partager sur WhatsApp
  • 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

 
GN⁺ 2024-03-26
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.

    • Les scores Lighthouse et PageSpeed Insights peuvent fluctuer. Pour ce genre de comparaison de performance, il vaut mieux lancer plusieurs mesures et regarder la médiane.
      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...
    • Content que ça te plaise. Cela dit, je m’attendais à ce que les indicateurs de performance s’améliorent davantage. Si ça ne te dérange pas, j’aimerais jeter un œil à la sortie du site statique avant application de Jampack.
      georges [at] divriots [dot] com
  • Ça me rappelle le module PageSpeed pour Apache et Nginx : https://developers.google.com/speed/pagespeed/module

  • 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.

    • Si on doit déployer une sorte d’assembleur ultra-optimisé pour du HTML et du CSS, je ne suis pas sûr qu’on aille dans la bonne direction.
      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-settings définis dans le CSS.

    • Oui, il y a beaucoup de choses intéressantes à faire côté polices. Dans la TODO, il y a l’ajout automatique de polices système de remplacement avec les bonnes métriques afin d’améliorer automatiquement le CLS.
      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.
    • Avec les polices du navigateur/système, on peut optimiser jusqu’à une taille de police de 0 ; je ne suis pas sûr qu’il soit nécessaire de faire autre chose.
  • 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 :hover sont 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

    • Si le CSS fait moins de 50 Ko, il suffit de l’inliner. Si vous avez plus de 50 Ko de CSS, c’est probablement que quelque chose ne va pas.
      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 ?

    • Non. Il utilise le lazy loading natif du navigateur. Les principaux navigateurs interprètent l’attribut 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.
    • Comme l’a indiqué @lelandfe, Jampack utilise le 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.

    • Hugo, Zola et Jekyll, par exemple.
      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.

    • S’il n’y a pas d’images, l’intérêt est effectivement limité. Et comme Jampack améliore automatiquement la compatibilité navigateur, la taille finale du CSS peut aussi augmenter.
      On peut désactiver cette fonction en définissant browserlist sur une chaîne vide : https://jampack.divriots.com/features/browser-compatibility/