[Web] avifとwebpフォーマットを使用して画像を最適化する

2026-02-05 hit count image

Pythonを使用してavifとwebpフォーマットの画像を生成し、LighthouseのServe images in next-gen formats問題を解決する方法について説明します。

目次

概要

GoogleChromeブラウザでは、ウェブページのパフォーマンスを測定できるLighthouseという機能を提供しています。この機能を使用すると、ウェブページの全体的なパフォーマンスを確認でき、次のように問題点も確認できます。

Optimization images - Lighthouse serve images in next-gen formats issue of images

このブログ記事では、ウェブページで画像フォーマットを最適化してServe images in next-gen formats問題を解決する方法について説明します。

avifとwebpフォーマット

Serve images in next-gen formats問題を解決するには、avifフォーマットまたはwebpフォーマットの画像を提供する必要があります。avifwebpフォーマットの画像は、IEを除くほとんどのモダンブラウザでサポートされている画像フォーマットです。

Pythonでavifとwebpフォーマットの画像を生成

このブログ記事では、jpgまたはpngフォーマットの画像ファイルをPythonを使用してavifwebpフォーマットの画像を生成する方法について説明します。

Pythonを使用してavifまたはwebpフォーマットの画像を生成するには、Pillowpillow-avif-pluginライブラリをインストールする必要があります。次のコマンドを使用してPillowpillow-avif-pluginライブラリをインストールします。

pip install Pillow pillow-avif-plugin

PillowPythonで画像を扱うためのライブラリであり、pillow-avif-pluginPillowライブラリを使用して画像のフォーマットを変更する際に、avifフォーマットで保存できるようにするライブラリです。

次にoptimization_images.pyファイルを作成し、次のように修正します。

import os
import glob
from PIL import Image
import pillow_avif

target_folder = './assets'
files = glob.glob(f'{target_folder}/**/*.jpg', recursive=True) + glob.glob(f'{target_folder}/**/*.png', recursive=True)

for f in files:
    print(f)
    title, ext = os.path.splitext(f)
    webp_file = title + '.webp'
    avif_file = title + '.avif'

    if os.path.isfile(webp_file) == False:
        img = Image.open(f)
        img.save(webp_file, format='webp')
        img.close()

    if os.path.isfile(avif_file) == False:
        img = Image.open(f)
        img.save(avif_file, format='AVIF' )
        img.close()

ではソースコードをもう少し詳しく見てみましょう。

私は画像ファイルをassetsフォルダに保存しています。もし画像ファイルを別のフォルダに保存している場合は、次の部分を修正してください。

...
target_folder = './assets'
...

画像を保存したフォルダ内のすべてのjpgpngフォーマットのファイルを検索します。

...
files = glob.glob(f'{target_folder}/**/*.jpg', recursive=True) + glob.glob(f'{target_folder}/**/*.png', recursive=True)
...

次にすべてのファイルをループしながらファイルフォーマットを変更します。ファイルフォーマットを変更し、フォーマットに合わせてファイル名も変更するためにos.pathを使用してファイル名を準備しました。

...
for f in files:
  title, ext = os.path.splitext(f)
  webp_file = title + '.webp'
  avif_file = title + '.avif'
  ...

次に、webpフォーマットのファイルが存在するか確認し、存在しない場合は、既存のファイルをwebpフォーマットに変更して保存します。

...
for f in files:
    ...
    if os.path.isfile(webp_file) == False:
        img = Image.open(f)
        img.save(webp_file, format='webp')
        img.close()
    ...

同様に、avifフォーマットのファイルが存在するか確認し、存在しない場合は、既存のファイルをavifフォーマットに変更して保存します。

...
for f in files:
    ...
    if os.path.isfile(avif_file) == False:
        img = Image.open(f)
        img.save(avif_file, format='AVIF' )
        img.close()

これでjpgまたはpngフォーマットの画像ファイルをavifwebpフォーマットに変更するPythonスクリプトを作成しました。

avifとwebpファイルの生成

では作成したoptimization_images.pyファイルを実行してavifwebpフォーマットファイルを生成してみましょう。avifwebpフォーマットファイルを生成するために次のコマンドを実行してPythonスクリプトを実行します。

python optimization_images.py

すると次のように画像ファイルリストを確認でき、avifwebpフォーマットファイルが生成されていることを確認できます。

...
./assets/images/category/flutter/2023/RefreshIndicator/refreshindicator_new_data_with_no_data.png
./assets/images/category/flutter/2023/RefreshIndicator/refreshindicator_pull_to_refresh.png
./assets/images/category/flutter/2023/RefreshIndicator/refreshindicator_no_data.png
./assets/images/category/flutter/2023/RefreshIndicator/listview.png
./assets/images/category/flutter/2023/RefreshIndicator/refreshindicator_refresh_no_data.png
./assets/images/category/flutter/2023/find_child_and_parent_widget/basic_app.png

タグ

では生成したavifwebpフォーマットファイルをウェブページで使用する方法について説明します。ウェブページで複数のフォーマットの画像を使用するには、<picture />タグと<source />タグを使用する必要があります。次のように<picture />タグと<source />タグを使用してavifwebpフォーマットを読み込むように設定します。

<picture>
  <source srcset="example.avif" type="image/avif" />
  <source srcset="example.webp" type="image/webp" />
  <img src="example.png" alt="example file" />
</picture>

このように<picture /><source />タグを使用すると、ブラウザがサポートするフォーマットの画像をダウンロードして表示するようになります。

完了

これでウェブページのパフォーマンス向上のために新しい画像フォーマットであるavifwebpファイルを生成し、<picture /><source />タグを使用して画像読み込みを最適化する方法について説明しました。Lighthouseでよく指摘される事項なので、この機会に覚えておくと良いでしょう。もしブラウザではなくローカルやCI環境でLighthouseを実行する方法について知りたい方は、下のリンクを参考にしてください。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts