Transcript
00:00:00今回は Bun 1.3.14 で追加された内蔵画像処理 API「Bun Image」をご紹介します。ネイティブの依存関係なしで画像の
00:00:06リサイズ、切り抜き、異なるフォーマット間での変換を行うことができ、
00:00:10処理のすべてがメインスレッド外で実行されるため、処理中もサーバーがブロックされません。
00:00:14しかし、Bun はすでにランタイムであり、パッケージマネージャーであり、バンドラーであり、テストランナーでもあります。
00:00:19そこに画像処理まで追加されるとは、やりすぎなのでしょうか?それとも、Bun の今後の方向性を示す
00:00:24大きなメッセージなのでしょうか?チャンネル登録をして確かめてみましょう。
00:00:30JavaScript でサーバー上の画像を処理したことがある方なら、知らず知らずのうちに「Sharp」という
00:00:35ライブラリを使っていたかもしれません。npm で週に 5,500 万回以上ダウンロードされており、
00:00:41Next.js の内部でも画像最適化に使われています。しかし Sharp は「libvips」というネイティブバイナリに依存しているため、
00:00:47インストールするたびにプラットフォームに合ったビルドを取得する必要があります。Docker のビルドや
00:00:51CI パイプラインがこれが原因で失敗した経験がある方なら、その面倒臭さがよく分かるはずです。そこで Bun は
00:00:57ランタイム自体に画像処理機能を組み込むことにしました。これがほとんどのベンチマークで Sharp よりも高速です。
00:01:02メタデータの読み込みは最大 70 倍速く、リサイズも約 30%高速です。多くの開発者は、
00:01:08なぜ Bun がこれを追加したのか戸惑っていますが、私にはその目指すところが少し見えている気がします。
00:01:13それについては後でお話しするとして、まずは Bun Image API の使い方をいくつかのデモを通して見ていきましょう。
00:01:17今回は、巨大な画像を使用している私のブログ(静的な Waku サイト)で試してみたいと思います。
00:01:22手始めに、私の顔写真であるプロフィール画像を最適化するシンプルなスクリプトを見てみましょう。
00:01:27なんと、ファイルサイズを 99%も削減することができました。驚異的な数字です。
00:01:33その仕組みを見てみましょう。まず画像を取得します。ここでは `Bun.image` を使用していますが、
00:01:37`Bun.file` と image 関数を組み合わせることも可能です。次に、サイズを縮小するために画像をリサイズします。幅を 800 ピクセルに指定し、
00:01:43高さはアスペクト比に基づいて自動的に計算されます。もちろん、必要であれば
00:01:47ここで高さを指定することもできます。そして、品質を下げた WebP 形式を出力フォーマットとして指定します。もちろん
00:01:52他の出力フォーマットもサポートされています。最後に、新しい画像をファイルに出力します。
00:01:56これは Promise を返すため、`await` キーワードが必要です。これだけでいかに簡単に実装できるかが分かります。
00:02:01実際、ここにあるコードの一部は不要なので、削除してさらにシンプルにすることも可能です。
00:02:06また、リサイズフィルターを設定してリサンプリングカーネルを変更し、画像サイズをさらに削減することもできます。
00:02:10画像の回転や反転も可能で、これは非常に便利です。明るさや彩度を変更することさえでき、
00:02:15ユニークな見た目の画像を作ることもできます。しかし、低速なネットワーク環境において非常に賢い方法があります。
00:02:19それは、placeholder 関数を使って、メイン画像の読み込み中にぼかした画像を自動的に表示することです。
00:02:23そのために、ブログ画像が格納されているディレクトリ内で、指定した拡張子を持つすべてのファイルをループ処理する
00:02:29コードを用意しています。各画像はクロップされずに縮小され、アップスケールされることなくリサイズされます。
00:02:34そして画像ごとにプレースホルダーを作成します。これにより ThumbHash が生成され、
00:02:39任意の画像を 28 バイトのハッシュにエンコードするため、ぼかしプレースホルダーとして最適です。
00:02:45このハッシュはプレースホルダーオブジェクトに追加され、ファイルに書き込まれます。
00:02:49出力結果は次のようになります。ここで、プレースホルダーに別の小さな WebP 画像ではなく
00:02:53Base64 画像を使用する理由は、それを取得するためのネットワークリクエストを発生させないためです。
00:02:58したがって、すべてのプレースホルダーをインポートし、メイン画像の読み込みを待つ間の CSS の背景画像として
00:03:02設定すれば、ブログ上のすべての画像でこの機能が動作します。
00:03:07もし MDX ファイル内の単一の画像に対して行いたい場合は、Base64 コードを手動で追加するだけで、
00:03:11同じように機能します。なお、JPEG 画像の場合は `progressive` を `true` に設定することでも
00:03:16同様の動作を実現できます。もちろん、Bun Image がサポートしている機能はこれだけにとどまりません。
00:03:20S3 互換バケットからの画像取得や、バケットへの画像保存、画像パイプラインをレスポンスボディとして直接利用すること、
00:03:24特定の OS がサポートしていない場合のフォールバックフォーマットの設定なども可能です。
00:03:28では、これを使う価値はあるでしょうか?すでに Bun を使っているなら、間違いなく採用すべきです。
00:03:33しかし Node.js を使っている場合、Sharp は非常に優れていて実績もあるため、
00:03:37画像処理のためだけにまったく異なるランタイムに変更する必要はないでしょう。
00:03:41Bun がこの機能を追加した背景には、さらに大きな理由があると言ったのを覚えていますか?
00:03:45ここ 1 年間の Bun の動向を見てみると、内蔵 SQLite、S3、Postgres、そして今回の画像処理と、
00:03:49認証とメール機能を除けば、フルスタックアプリに必要なものがほぼすべて揃っています。
00:03:54これにより、ある疑問が湧いてきます。Bun は JavaScript 版の Laravel や Rails を
00:03:59ランタイムレベルで構築しようとしているのではないでしょうか?もしそうだとすれば、
00:04:04次に手掛けるのは認証機能のはずです。もしそうなら、この動画で一番最初に聞いたことを思い出してください。
00:04:11しかし残念ながら、現在の Bun を語る上で、Zig から Rust への大規模な書き直しに触れないわけにはいきません。
00:04:15うまくいけば次期バージョンで登場する予定です。すべてが順調に進むことを祈りましょう。
00:04:20Zig といえば、Vercel の言語である「Zero」についてもっと知りたいですか?Zig に似ていますが Zig ではなく、
00:04:25AI エージェント向けに構築されたその言語については、James のこちらの動画をチェックしてみてください。
00:04:29Zig ではなく、AI エージェント向けに構築されたその言語については、James のこちらの動画をチェックしてみてください。