PHPのGD、サーバーごとにWebP/AVIF対応が違う。本番で確認した話

  • URLをコピーしました!

PNGじゃなくWebP/AVIFの方が良いのでは、と思った

アイキャッチを自動生成する仕組みを作ったとき、最初は特に考えずPNGで出力していました。ただ作りながら、「今どきならPNGよりWebPやAVIFの方が良いのでは」という考えが頭に浮かびました。ブラウザの対応状況はほぼ揃ってきていますし、圧縮率も優れています。

これまで色々なブログの運用を見てきた中で、画像がどんどん溜まっていって重くなっていくサイトを何度も見てきました。
このブログは今はまだ記事数が少ないので、後からまとめて直すより、今のうちに手を打っておきたいと思いました。プラグインで一括圧縮するという手もありますが、なるべくプラグインには頼りたくなかったので、画像を生成するコード側で最初から圧縮した形式にしておきたい、と考えました。

アイキャッチを実ファイルとして自動生成する仕組みそのものについては、こちらの記事で紹介しています。

ローカルでは問題なく使えそうだった

PHPで画像を生成しているGD拡張が、実際にWebPやAVIFに対応しているかをまず確認しました。gd_info()という関数で、GDが対応している機能の一覧を確認できます。

print_r(gd_info());

開発環境(ddev)で実行したところ、こんな結果が返ってきました。

[WebP Support] => 1
[AVIF Support] => 1

両方ともサポートされています。この結果だけを見ると、「じゃあ切り替えよう」となってもおかしくない状況でした。

本番で確認したら、そもそも項目が無かった

念のため、本番サーバーでも同じコマンドを実行してもらいました。結果は次のようなものでした。

Array
(
    [GD Version] => bundled (2.1.0 compatible)
    [FreeType Support] => 1
    [FreeType Linkage] => with freetype
    [T1Lib Support] => 1
    [GIF Read Support] => 1
    [GIF Create Support] => 1
    [JPEG Support] => 1
    [PNG Support] => 1
    [WBMP Support] => 1
    [XPM Support] => 1
    [XBM Support] => 1
    [JIS-mapped Japanese Font Support] =>
)

WebP SupportAVIF Supportの項目自体が存在しません。ローカルでは当たり前のように使えていた機能が、本番では最初から選択肢に入っていなかった、ということです。恥ずかしながら、GDというライブラリの存在自体もこれまでよく知らずに使っていましたし、サーバーによって対応している画像フォーマットが違う、ということすら知りませんでした。

「2.1.0」という表記に惑わされかけた

最初、GD Version => bundled (2.1.0 compatible)という表示を見て、「バージョンが古いから対応していないんだろう」と考えました。ただこれは少し不正確な理解でした。

このbundled (2.1.0 compatible)という表記は、PHPに同梱されているGDライブラリが昔から表示している固定の互換性文字列で、実際のビルド内容やバージョンとは直接結びついていません。新しいPHPでも同じ表記が出ることがあります。

判断材料にすべきは、バージョンの表記そのものではなく、[WebP Support][AVIF Support]という項目が出力に存在するかどうかです。存在しなければ、そのPHPに組み込まれているGDはそもそもその形式でビルドされていない、ということになります。

今回はPNGのまま、圧縮だけ効かせることにした

本番のGDがWebP/AVIFに対応していない以上、無理に使おうとするとimagewebp()が未定義関数としてエラーになり、記事の保存自体が失敗してしまいます。ホスティング側の対応状況が変わらない限りどうにもならないので、今回はPNGのまま進めることにしました。

その代わり、PNGの可逆圧縮レベルを最大にして、画質に影響を与えない範囲でファイルサイズを削れないか試しました。

imagepng( $img, null, 9 ); // 9 = 最大圧縮(可逆なので画質は変わらない)

デフォルトの圧縮設定と比べると、同じ画像で約1割ほどファイルサイズが小さくなりました。WebP化ほどの効果はありませんが、見た目を一切変えずにできる範囲の対策として、これで妥協することにしました。

この画像生成では、サーバー環境の違いによる不具合が他にも見つかりました。
詳しくはこちらの記事で紹介しています。

まとめ

  • 新しい画像形式を採用する前に、実際に使うサーバー環境で対応状況を確認する。ローカルで動くことと、本番で動くことは別
  • gd_info()のようなライブラリの機能一覧では、バージョン表記そのものよりも、個別の機能フラグが存在するかどうかで判断する
  • 使いたい技術が使えないと分かったら、その場でできる範囲の次善策(今回は圧縮レベルの見直し)に切り替える
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Web制作会社にてフロントエンド業務に携わる一方、個人でブログを書いたりサイト制作やシステム構築にいそしむ。元家具職人。
https://rcwas.com/

目次