- Jampack ist ein Nachbearbeitungs-Tool, das die Ausgaben eines Static Site Generators entgegennimmt und die User Experience sowie die Core Web Vitals optimiert; es ist weder Bundler noch Framework
- Es wandelt
<img> und <picture> in HTML in responsive Bilder um und fügt automatisch Formate wie WebP und AVIF, srcset, sizes, width, height, loading="lazy", decoding="async" usw. hinzu
- CDN-Bilder können über URL-Parameter-basierte
srcset responsiv verarbeitet werden; externe Bilder lassen sich unter _jampack herunterladen und durch optimierte lokale Bilder ersetzen
- Above-the-fold-Assets werden mit hoher Priorität behandelt, kleine Bilder werden ins HTML inline eingebettet, und below-the-fold-Bilder sowie iframes werden lazy geladen
- Die Anwendung erfolgt, indem im Ausgabeordner des Static-Site-Builds
npx @divriots/jampack./dist ausgeführt wird; in einem zweiten Durchlauf werden auch CSS, JS, HTML, SVG und Bilder komprimiert
Die Rolle von Jampack
- Jampack optimiert statische Websites, indem es die von einem Static Site Generator, also einem SSG, erzeugten Ergebnisse als Eingabe verwendet
- Ziel ist es, die User Experience und die Core Web Vitals zu verbessern
- Die README grenzt Jampack als „weder Bundler noch Framework“ ab
- Der Einführungsartikel ist unter Read the introduction blog post verfügbar
Bildoptimierung
- Normale
<img>-Elemente werden in responsive Bilder umgewandelt
- Für das ursprüngliche
src wird eine WebP-Datei erstellt und srcset hinzugefügt
- Attribute wie
sizes="100vw", loading="lazy", decoding="async", width und height werden hinzugefügt
<picture>-Elemente werden in eine responsive Struktur mit mehreren Bildformaten umgewandelt
- Ein
<source type="image/avif"> für AVIF wird hinzugefügt
- Ein
<source type="image/webp"> für WebP wird hinzugefügt
- Auch das ursprüngliche
<img> erhält srcset, sizes, loading, decoding, width und height
- Die Bildoptimierungsfunktion verweist auf die Dokumentation
optimize-images, der entsprechende Link in der README ist jedoch ein relativer Pfad
Verarbeitung von CDN- und externen Bildern
- CDN-Bilder können ihre Remote-URL beibehalten und gleichzeitig um ein responsives
srcset ergänzt werden
- Das Beispiel fügt einer Unsplash-Bild-URL Parameter wie
w, fit=min und auto=format hinzu, um Kandidaten in mehreren Breiten zu erzeugen
- Auch dem ursprünglichen Bild werden
loading="lazy", decoding="async" und sizes="100vw" hinzugefügt
- Externe Bilder können heruntergeladen und anschließend durch optimierte lokale Dateien ersetzt werden
- Das Beispiel wandelt ein externes Unsplash-Bild in einen Pfad wie
_jampack/ab99b9d280ce4cf7cfc810b59f3a7739.jpg.webp um
- Das umgewandelte Bild enthält
width, height, srcset, sizes, loading und decoding
Above-the-fold sowie Optimierung von CSS und Links
- Jampack optimiert above-the-fold-Assets separat
- Bilder werden mit höherer Priorität geladen
- Kleine Bilder werden in HTML eingebettet
- Below-the-fold-Assets werden lazy geladen
- Bilder und iframes sind Ziele für Lazy Loading
- Critical CSS wird in HTML inline eingebettet
- Ziel ist es, FOUC zu vermeiden, das beim Herunterladen und Parsen von Stylesheets auftreten kann
- Das übrige CSS wird verzögert geladen
- Link-Prefetching ist eine Funktion, um künftige Seitenwechsel zu beschleunigen
- Mit quicklink lässt sich dies dynamisch verarbeiten, wenn Links in den Viewport gelangen
Asset-Komprimierung und Ausführung
- Jampack komprimiert in einem zweiten Durchlauf alle Assets, die zuvor nicht verändert wurden, und behält dabei denselben Namen und dasselbe Format bei
- Die Komprimierungstools nach Dateiendung sind:
- Wenn sich die statische Website im Ordner
dist befindet, wird sie mit folgendem Befehl ausgeführt
npx @divriots/jampack ./dist
Anwendungsfälle und Bedeutung des Namens
1 Kommentare
Meinungen auf Hacker News
Genau das Tool, nach dem ich gesucht habe. Für diese Art von Bildoptimierung habe ich bisher selbst Skripte auf Basis von Sharp geschrieben, aber Jampack ersetzt das vollständig und funktioniert deutlich besser.
Nachdem ich meine statische Quarto-Site gebaut und Jampack darüber laufen gelassen habe, war die Ordnergröße um 32 % kleiner, und bisher sehe ich keine nennenswerten Nachteile.
Laut PageSpeed Insights lag vor Jampack die mobile Performance bei 52, Barrierefreiheit bei 73, Best Practices bei 100 und SEO bei 85; auf dem Desktop waren es Performance 90, Barrierefreiheit 75, Best Practices 100 und SEO 82.
Nach der Anwendung waren es mobil Performance 49, Barrierefreiheit 80, Best Practices 100, SEO 92 sowie auf dem Desktop Performance 85, Barrierefreiheit 82, Best Practices 100, SEO 91.
Es gibt auch Material dazu, dass „der Median aus 5 Lighthouse-Läufen doppelt so stabil ist wie ein einzelner Lauf“: https://developers.google.com/web/tools/lighthouse/variabili...
georges [at] divriots [dot] com
Erinnert mich an das PageSpeed-Modul für Apache und Nginx: https://developers.google.com/speed/pagespeed/module
Das GitHub-Repository ist ebenfalls archiviert: https://github.com/apache/incubator-pagespeed-ngx
Ist es vielleicht woandershin umgezogen?
Wow, das gefällt mir ziemlich gut. Ich werde es ausprobieren.
Falls jemand es nicht gut findet, würde ich gern hören, wo die Schwächen liegen. Für mich sieht es ähnlich aus wie das Kompilieren von C zu extrem hochoptimiertem Assembly: ein Tool, das zuverlässig etwas übernimmt, das ich nicht selbst machen möchte.
Meiner Meinung nach sollte man das einfachste und naheliegendste HTML und CSS schreiben können, und die Browser auf allen Geräten sollten es einfach gut rendern.
Wenn man wirklich so stark optimierte Artefakte ausliefern muss, wäre es vielleicht besser, HTML und CSS ganz zu überspringen, hochoptimiertes WebAssembly auszuliefern und Entwickler die Sprache verwenden zu lassen, die sie möchten.
Es wäre schön, Fonts anhand der Unicode-Bereiche der SSG-Ausgabe zu subsetten und OpenType-Achsen auf Basis der in CSS definierten
font-feature-settingsfestzuschreiben.Ich frage mich, ob du damit das „Festschreiben von OpenType-Achsen auf Basis von font-feature-settings“ meinst oder etwas anderes.
Font-Subsetting würde ich ebenfalls gern optimieren, aber ich weiß noch nicht genau, wie groß der Verbesserungsbereich wäre. Mich würde interessieren, ob du das schon einmal manuell gemacht hast.
Das Konzept, kritisches CSS zu identifizieren, das nicht in einem separaten Stylesheet liegen, sondern inline eingefügt werden sollte, finde ich interessant.
Ich hatte gehofft, es gäbe eine prinzipielle Methode, kritisches und nicht kritisches CSS zu unterscheiden. Zum Beispiel könnte man Nutzerinteraktionseffekte wie
:hoverimmer als nicht kritisch betrachten.Die verwendete Library rendert die Seite aber und schätzt dann bestmöglich, welche Regeln als kritisch gelten können; das ist etwas schade: https://github.com/GoogleChromeLabs/critters
Wenn du natürlich Fonts mit inline einbettest, kann ich das verstehen; aber wenn allein die übrigen Styles über 50 KB liegen, ist das meist der falsche Weg.
Ernsthaft: Inlining ist performance-technisch enorm gut, selbst im Vergleich zu einem warmen Cache, und der Punkt, ab dem externe Stylesheets oder Skripte besser werden, liegt höher als man denkt — nach üblichen Marktmaßstäben teils bei mehreren hundert KB.
Das Konzept des kritischen CSS wirkt auf mich wie ein defätistischer Ansatz, der versucht, etwas verschwendete Performance zurückzuholen, statt das eigentliche Problem zu beheben.
Allerdings ist das keine systematische Methode, sondern eine Einschätzung auf Basis leichter Erfahrung und Beobachtung. Es wäre schön, wenn jemand dieses Konzept sauberer messen würde, aber ich glaube nicht, dass ich das tun werde.
Das scheint mehrere Anwendungsfälle abzudecken, für die Leute überhaupt erst SSGs und Plugins auswählen — besonders wenn sie Astro oder Eleventy nehmen.
Gibt es einen Grund, das lieber als separaten Post-Build-Schritt zu haben? Rebuilds während der Entwicklung werden dadurch schneller, aber es wirkt wie ein Kompromiss gegenüber dem Risiko, subtile Bugs zu übersehen, die etwa durch das Hinzufügen von Image-Width-Angaben entstehen.
Aus der Sicht von jemandem, der Webseitenlayout-Arbeit hasst und sich weigert, sie zu lernen, sie aber gelegentlich trotzdem machen muss, sieht dieses Tool großartig aus.
Sieht gut aus. Persönlich mag ich es allerdings nicht, wenn ich unter den ersten sichtbaren Bereich einer Seite scrolle und dann auf Bilder warten muss.
Lädt das Standardverhalten nach dem Ende des Above-the-Fold-Contents den restlichen unteren Content im Hintergrund?
loading="lazy"als „dieses Bild/iframe erst laden, wenn es fast sichtbar ist“: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/im...Das Seitenverhältnis wird allerdings inline eingefügt, sodass sich das Layout nach dem Laden nicht verschiebt. Damit vermeidet man die größte Sünde von Lazy Loading.
loading="lazy".Aktuell gibt es keine Möglichkeit, dieses Verhalten zu ändern, aber man könnte eine Option hinzufügen, um Bilder unterhalb des ersten sichtbaren Bereichs nach dem vollständigen Laden der Seite im Hintergrund vorzuladen. Das ist eine ziemlich gute Idee.
Ich mache mir nur Sorgen, dass dann auch unnötige Bilder am Seitenende geladen werden. Als Option wäre es aber okay, weil jeder sie ein- oder ausschalten kann.
Welche Static-Site-Generatoren werden in Produktionsumgebungen verwendet? Ich habe das Gefühl, dass dieses Tool deren Ausgabe weiter optimieren könnte.
Zum Beispiel habe ich gestern den ganzen Tag damit verbracht, ein Beispiel nachzuvollziehen, um eine Divjoy-React-Website in schlichtes HTML umzuwandeln und aus einem S3-Bucket auszuliefern. Ich hätte nicht gedacht, dass es so schwierig ist, und hänge immer noch fest.
Idealerweise gäbe es etwas, das automatisch in einen S3-Bucket deployt und sogar die Domain verbindet. Es tut weh, dafür bezahlt zu haben, während der Entwickler verschwunden ist und Discord brachliegt. Deshalb bevorzuge ich immer FOSS.
Sie haben bis zu einem gewissen Grad einige dieser Funktionen.
Bei einem meiner Projekte hat sich nicht viel geändert. Zum Beispiel ist die gesamte Bundle-Größe gesunken, aber die gzip-Größe gestiegen, was für mich unterm Strich tatsächlich ein Nachteil war.
Trotzdem scheinen die CSS-Verbesserungen tatsächlich geholfen zu haben.
Die Idee wirkt großartig, und wenn das Projekt Bilder gehabt hätte, hätte es vermutlich geholfen.
Wenn du
browserlistauf einen leeren String setzt, kannst du diese Funktion deaktivieren: https://jampack.divriots.com/features/browser-compatibility/