Bun.Image macht Ihre gesamte Bild-Pipeline überflüssig
BBetter Stack
Computing/SoftwareInternet Technology
Transcript
00:00:00Das ist Bun Image, eine in Bun 1.3.14 integrierte Bildverarbeitungs-API, die das Grösse ändern,
00:00:06Zuschneiden und Konvertieren von Bildern zwischen verschiedenen Formaten ohne native Abhängigkeiten ermöglicht,
00:00:10und das Ganze läuft ausserhalb des Hauptthreads, was bedeutet, dass dein Server während der Verarbeitung
00:00:14nicht blockiert wird. Aber Bun ist doch bereits eine Laufzeitumgebung, ein Paketmanager, ein Bundler, ein Test-Runner
00:00:19und jetzt auch noch ein Bildverarbeiter? Ist das alles viel zu viel oder verrät es uns etwas
00:00:24Grösseres darüber, wohin sich Bun entwickelt? Abonniere den Kanal und lass es uns herausfinden.
00:00:30Wenn du schon mal Bilder auf dem Server mit JavaScript verarbeitet hast, hast du vielleicht eine Bibliothek namens
00:00:35Sharp verwendet, ohne es überhaupt zu wissen. Sie hat wöchentlich über 55 Millionen Downloads auf npm und wird sogar
00:00:41von Next.js im Hintergrund zur Bildoptimierung eingesetzt. Aber Sharp basiert auf einer nativen Binärdatei namens libvips,
00:00:47weshalb bei jeder Installation das passende Build für deine Plattform geladen werden muss. Und wenn du schon mal
00:00:51einen Docker-Build- oder CI-Pipeline-Fehler deswegen hattest, weisst du, wie frustrierend das ist. Deshalb hat sich Bun entschlossen,
00:00:57die Bildverarbeitung direkt in die Laufzeitumgebung einzubauen, und sie ist in den meisten
00:01:02Benchmarks tatsächlich schneller als Sharp. Das Lesen von Metadaten ist bis zu 70-mal schneller und das Skalieren etwa 30 % schneller. Nun sind viele
00:01:08Entwickler wirklich verwirrt, warum Bun das hinzugefügt hat, aber ich verstehe ungefähr, wohin das führt,
00:01:13und ich werde dir später mehr dazu erzählen. Schauen wir uns aber erst einmal ein paar Demos an, wie man
00:01:17die Bun-Image-API verwendet. Wir probieren das an meinem Blog aus, einer statischen Waku-Website,
00:01:22die ein paar riesige Bilder enthält. Zu Beginn schauen wir uns ein einfaches Skript an, das ein einzelnes Bild optimiert,
00:01:27nämlich das Profilbild mit meinem Gesicht, und die Dateigrösse lässt sich damit um unglaubliche 99 % reduzieren.
00:01:33Schauen wir uns an, wie das geht. Zuerst rufen wir das Bild ab – beachte, dass wir hier Bun.image verwenden, du könntest aber auch
00:01:37Bun.file mit der Image-Funktion nutzen. Dann skalieren wir das Bild, um seine Grösse zu verringern, indem wir eine Breite von 800 Pixeln vorgeben,
00:01:43wobei die Höhe automatisch basierend auf dem Seitenverhältnis berechnet wird. Wenn du möchtest,
00:01:47könnten wir diese hier ebenfalls angeben. Danach legen wir als Ausgabeformat WebP mit reduzierter Qualität fest. Natürlich
00:01:52werden auch andere Ausgabeformen unterstützt, und dann speichern wir das neue Bild als Datei,
00:01:56was ein Promise ist, weshalb das await-Schlüsselwort erforderlich ist. Und Sie sehen, wie einfach das ist.
00:02:01Tatsächlich ist all dieser Code hier überflüssig, wir können ihn also entfernen und den Code noch einfacher gestalten.
00:02:06Wir können auch einen Skalierungsfilter festlegen, den Resampling-Kernel ändern und die Bildgrösse weiter reduzieren.
00:02:10Wir können das Bild drehen oder spiegeln, was wirklich cool ist. Wir können sogar die Helligkeit oder
00:02:15Sättigung anpassen, was allerdings zu ziemlich merkwürdig aussehenden Bildern führen kann. Es gibt jedoch etwas sehr Cleveres,
00:02:19das du bei langsamen Verbindungen tun kannst: die Placeholder-Funktion nutzen, um automatisch
00:02:23ein verschwommenes Bild anzuzeigen, während das Hauptbild noch lädt. Dazu verwende ich diese Schleife,
00:02:29die jede einzelne Datei mit diesen Endungen in dem Verzeichnis durchläuft, das alle
00:02:34Blog-Bilder enthält. Jedes Bild wird also in der Grösse angepasst, verkleinert ohne zugeschnitten zu werden, und nicht
00:02:39hochskaliert. Dann erstellen wir für jedes Bild einen Platzhalter, der einen ThumbHash erzeugt, also
00:02:45jedes Bild in einen 28-Byte-Hash codiert – perfekt als Platzhalter für ein verschwommenes Bild.
00:02:49Dieser Hash wird einem Platzhalter-Objekt hinzugefügt und dann in eine Datei geschrieben,
00:02:53die so aussieht. Der Grund, warum der Platzhalter ein Base64-Bild und kein
00:02:58separates kleineres WebP-Bild ist, besteht darin, dass das Netzwerk keine zusätzliche Anfrage zum Abrufen stellen muss.
00:03:02Ich kann also alle Platzhalter importieren und sie als Hintergrundbild in CSS einfügen,
00:03:07während ich darauf warte, dass das Hauptbild geladen wird, was für jedes Bild auf meinem Blog funktioniert.
00:03:11Wenn du das für ein einzelnes Bild in einer MDX-Datei tun möchtest, kannst du den Base64-Code einfach
00:03:16manuell hinzufügen, was genauso gut funktioniert. Übrigens lässt sich ein ähnliches Verhalten
00:03:20auch mit JPEG-Bildern erzielen, indem man progressive auf true setzt. Natürlich gibt es noch viele weitere Dinge, die Bun Image
00:03:24unterstützt, auf die ich noch nicht eingegangen bin, wie das Abrufen von Bildern aus einem S3-kompatiblen
00:03:28Bucket, das Speichern von Bildern in einem Bucket, die Verwendung der Image-Pipeline als gültiger Response-Body
00:03:33sowie die Konfiguration eines Fallback-Formats, falls ein bestimmtes Betriebssystem eines nicht unterstützt.
00:03:37Lohnt sich das Ganze also? Nun, wenn du bereits Bun nutzt, dann auf jeden Fall, das ist ein Kinderspiel.
00:03:41Wenn du jedoch Node verwendest, funktioniert Sharp hervorragend und ist kampferprobt,
00:03:45und es besteht kein Grund, nur für die Bildverarbeitung zu einer völlig anderen Laufzeitumgebung zu wechseln.
00:03:49Erinnerst du dich, als ich sagte, es gäbe einen wichtigeren Grund für diesen Schritt von Bun? Wenn man sich ansieht, was Bun
00:03:54im letzten Jahr alles gemacht hat – integriertes SQLite, S3, Postgres und jetzt Bilder –, ist das im Grunde
00:03:59alles, was man für eine Full-Stack-App braucht, abgesehen von vielleicht Authentifizierung und E-Mail. Das lässt mich fragen:
00:04:04Versucht Bun, das Laravel oder Rails für JavaScript zu bauen, aber direkt auf Runtime-Ebene? Wenn dem so ist,
00:04:11wird als Nächstes die Authentifizierung dran sein. Und wenn das passiert, erinner dich daran: Du hast es hier zuerst gehört.
00:04:15Leider kann man heutzutage über Bun sprechen, ohne den riesigen Rewrite von Zig zu Rust zu erwähnen,
00:04:20der – hoffentlich – in der nächsten Version erscheinen wird. Hoffen wir, dass alles glattgeht.
00:04:25Apropos Zig: Wenn du mehr über Vercels Language Zero erfahren möchtest, das wie Zig aussieht,
00:04:29aber kein Zig ist und für KI-Agenten entwickelt wurde, schau dir dieses Video von James an.