Google は、画像によるウェブサイトの肥大化について頻繁に記事を公開しています。Lighthouse などのツールでは、画像の読み込みが読み込み時間の増加や、より重要なリソースからの帯域幅の消費など、ユーザー エクスペリエンスに悪影響を及ぼしている場合にハイライト表示されます。この問題を解決する方法の 1 つは、最新の圧縮を使用して画像のファイルサイズを小さくすることです。ウェブ デベロッパー向けの新しいオプションとして、AVIF 画像形式があります。このブログ投稿では、AVIF のオープンソース ツールの最新のアップデートについて説明します。また、libaom と libavif のエンコード ライブラリを紹介し、これらのライブラリを使用して AVIF 画像を効率的にエンコードするチュートリアルも含まれています。
AVIF は、AV1 動画コーデックに基づく画像形式で、Alliance for Open Media によって標準化されています。AVIF は、JPEG や WebP などの他の画像形式と比べて圧縮率が大幅に向上しています。具体的な削減率はコンテンツ、エンコード設定、品質目標によって異なりますが、Google と他社では、JPEG と比較して 50% を超える削減率が確認されています。
また、AVIF では、ハイ ダイナミック レンジと広色域、フィルム グレインの合成、プログレッシブ デコードなどの新しい画像機能のコーデックとコンテナのサポートが追加されています。
新機能
Chrome M85 で AVIF のサポートが開始されて以来、オープンソース エコシステムでの AVIF のサポートは多くの面で改善されています。
Libaom
Libaom は、Alliance for Open Media の企業によって維持されているオープンソースの AV1 エンコーダとデコーダであり、Google や他のメンバー企業の多くの本番環境サービスで使用されています。libaom 2.0.0 リリース(Chrome が AVIF のサポートを追加した頃)と最近の 3.1.0 リリースの間に、静止画像エンコードの大幅な最適化がコードベースに追加されました。次のようなアクセサリーが含まれます。
- マルチスレッドとタイル エンコードの最適化。
- メモリ使用量が 5 倍削減されます。
- 以下のグラフに示すように、CPU 使用量が 6.5 倍削減されます。
これらの変更により、AVIF のエンコード コストが大幅に削減されます。特に、サイト上で最も頻繁に読み込まれる画像や優先度の高い画像のエンコード コストが削減されます。サーバーやクラウド サービスで AV1 のハードウェア アクセラレーション エンコードが利用可能になるにつれて、AVIF 画像の作成コストは引き続き低下します。
Libavif
AVIF のリファレンス実装である Libavif は、Chrome で AVIF 画像のデコードに使用されるオープンソースの AVIF の muxer とパーサーです。libaom と組み合わせて、既存の非圧縮画像から AVIF 画像を作成したり、既存のウェブ画像(JPEG、PNG など)からトランスコードしたりすることもできます。
Libavif は最近、より高度な libaom エンコーダ設定との統合など、より広範なエンコーダ設定のサポートを追加しました。libyuv を使用した高速 YUV から RGB への変換や事前に乗算されたアルファなど、処理パイプラインの最適化により、デコード プロセスがさらに高速化されています。最後に、libaom 3.1.0 で新しく追加されたオールイントラ エンコード モードのサポートにより、上記の libaom の改善がすべてもたらされます。
avifenc による AVIF 画像のエンコード
AVIF を簡単にテストするには、Squoosh.app を使用します。Squoosh は libavif の WebAssembly バージョンを実行し、コマンドライン ツールと同じ多くの機能を公開します。AVIF を新旧の他の形式と簡単に比較できます。Node アプリを対象とした Squoosh の CLI バージョンもあります。
ただし、WebAssembly はまだ CPU のすべてのパフォーマンス プリミティブにアクセスできるわけではないため、libavif を最速で実行する場合は、コマンドライン エンコーダ avifenc をおすすめします。
AVIF 画像をエンコードする方法を確認するため、上記の例で使用した同じソース画像を使用したチュートリアルを紹介します。開始するには、以下のものが必要です。
また、zlib、libpng、libjpeg のデベロッパー パッケージもインストールする必要があります。Debian と Ubuntu の Linux ディストリビューションのコマンドは次のとおりです。
sudo apt-get install zlib1g-dev
sudo apt-get install libpng-dev
sudo apt-get install libjpeg-dev
コマンドライン エンコーダ avifenc をビルドする
1. コードを取得する
libavif のリリースタグを確認します。
git clone -b v0.9.1 https://github.com/AOMediaCodec/libavif.git
2. ディレクトリを libavif に変更します。
cd libavif
avifenc と libavif をビルドするように構成する方法はいくつかあります。詳細については、libavif をご覧ください。 ここでは、AVIF エンコーダとデコーダのライブラリ libaom に静的にリンクされるように avifenc をビルドします。
3. libaom を取得してビルドする
libavif 外部依存関係ディレクトリに移動します。
cd ext
次のコマンドは、libaom ソースコードを取得し、libaom を静的にビルドします。
./aom.cmd
ディレクトリを libavif に変更します。
cd ..
4. コマンドライン エンコード ツール avifenc をビルドする
avifenc のビルド ディレクトリを作成することをおすすめします。
mkdir build
ビルド ディレクトリに移動します。
cd build
avifenc のビルドファイルを作成します。
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=0 -DAVIF_CODEC_AOM=1 -DAVIF_LOCAL_AOM=1 -DAVIF_BUILD_APPS=1 ..
avifenc をビルドします。
make
avifenc のビルドが完了しました。
avifenc コマンドライン パラメータについて
avifenc は次のコマンドライン構造を使用します。
./avifenc [options] input.file output.avif
このチュートリアルで使用する avifenc の基本パラメータは次のとおりです。
Avifenc | |
---|---|
--min 0 | 色の最小量子化器を 0 に設定 |
--max 63 | 色の最大量子化器を 63 に設定 |
--minalpha 0 | アルファの最小量子化器を 0 に設定 |
--maxalpha 63 | アルファの最大量子化器を 63 に設定 |
-a end-usage=q | レート コントロール モードを固定品質(Q)モードに設定する |
-a cq-level=Q | 色とアルファの両方の量子化レベルを Q に設定します。 |
-a color:cq-level=Q | 色の量子化レベルを Q に設定する |
-a alpha:cq-level=Q | アルファの量子化レベルを Q に設定する |
-a tune=ssim | SSIM 用にチューニングする(デフォルトは PSNR 用にチューニング) |
--jobs J | J ワーカー スレッドを使用(デフォルト: 1) |
--speed S | エンコーダの速度を 0 ~ 10 の範囲で設定します(遅い順に 0 ~ 10、デフォルト: 6)。 |
cq-level オプションは、色またはアルファの品質を制御するために量子化レベル(0 ~ 63)を設定します。
デフォルト設定で AVIF 画像を作成する
avifenc を実行するための最も基本的なパラメータは、入力ファイルと出力ファイルの設定です。
./avifenc happy_dog.jpg happy_dog.avif
イメージをエンコードするには、次のコマンドライン(量子化レベル 18 など)をおすすめします。
./avifenc --min 0 --max 63 -a end-usage=q -a cq-level=18 -a tune=ssim happy_dog.jpg happy_dog.avif
Avifenc には、品質と速度の両方に影響を与えるオプションが多数用意されています。オプションの詳細を確認するには、./avifenc
を実行します。
これで、独自の AVIF 画像が作成されました。
エンコーダの高速化
マシンのコア数に応じて変更することをおすすめするパラメータの 1 つが --jobs
パラメータです。このパラメータは、avifenc が AVIF 画像の作成に使用するスレッド数を設定します。
コマンドラインで実行してみてください。
./avifenc --min 0 --max 63 -a end-usage=q -a cq-level=18 -a tune=ssim --jobs 8 happy_dog.jpg happy_dog.avif
これにより、AVIF イメージの作成時に 8 つのスレッドを使用するように avifenc に指示します。これにより、AVIF エンコードが約 5 倍高速化されます。
Largest Contentful Paint(LCP)への影響
画像は、Largest Contentful Paint(LCP)指標の一般的な候補です。LCP 画像の読み込み速度を改善するための一般的な推奨事項の一つは、画像を最適化することである。リソースの転送サイズを小さくすることで、リソースの読み込み時間を改善できます。これは、画像である LCP 候補を扱う際に対象とする 4 つの主要なフェーズの 1 つです。
画像を最適化する場合は、画像 CDN を使用することを強くおすすめします。ウェブサイトのビルドプロセスで画像最適化パイプラインを設定したり、エンコーダ バイナリを手動で使用して画像を手動で最適化したりするよりも、はるかに手間がかかりません。ただし、一部のプロジェクトでは、画像 CDN の費用が高すぎる場合があります。このような場合は、avifenc エンコーダで最適化する際に次の点を考慮してください。
- エンコーダが提供するオプションをよく理解してください。AVIF で利用可能なエンコード機能を試すことで、十分な画質を維持しながらさらに容量を削減できる場合があります。
- AVIF は、非可逆エンコードと可逆エンコードの両方をサポートしています。画像の内容によっては、あるタイプのエンコードが別のタイプのエンコードよりも優れている場合があります。たとえば、通常は JPEG として提供される写真は、非可逆エンコードが最適ですが、通常は PNG として提供されるシンプルなディテールや線画を含む画像には、可逆エンコードが最適です。
- imagemin のコミュニティ サポートを備えたバンドラを使用する場合は、imagemin-avif パッケージを使用して、バンドラが AVIF 画像のバリエーションを出力できるようにすることを検討してください。
AVIF をテストすることで、LCP 候補が画像である場合にウェブサイトの LCP 時間を改善できる可能性があります。LCP の最適化について詳しくは、LCP の最適化に関するガイドをご覧ください。
まとめ
libaom、libavif などのオープンソース ツールを使用すると、AVIF を使用してウェブサイトで最適な画質とパフォーマンスを実現できます。この形式はまだ比較的新しく、最適化とツールの統合が積極的に開発されています。質問、コメント、機能リクエストがある場合は、av1-discuss メーリング リスト、AOM GitHub コミュニティ、AVIF ウィキにお問い合わせください。