Apache

【Apache】Webp画像を設定する方法

ApacheでWebP画像を配信する設定です。MIMEタイプはimage/webpで、AddType image/webp .webpで追加します。mod_rewriteでjpeg・pngへのリクエストを同名の.webpに差し替え、Acceptヘッダーで対応ブラウザにだけ返す方法とVary: Acceptの付け方を解説します。

この記事の目次
  1. 【Apache】Webp画像を設定する方法
  2. Webp画像に対応しているブラウザとそうでないブラウザを判定する

Webp画像とは、Googleが開発している圧縮率がとても良い画像ファイルです。
それをApacheを使って、jpegやpngへのリクエストをwebp拡張子のファイルに差し替えます。
Webp画像に対応しているブラウザとそうでないブラウザがあるので、対応しているブラウザにのみWebp画像を返します。

先に結論です。WebPのMIMEタイプ(Content-Type)はimage/webpで、Apacheで認識されていない場合は.htaccessかhttpd.confにAddType image/webp .webpを1行足します。
jpegやpngへのリクエストを同名の.webpに差し替えるには、mod_rewriteで「ブラウザのAcceptヘッダーにimage/webpがある」かつ「同名の.webpファイルが存在する」ときだけ書き換えます。
なお、ここで行うのはリクエストの振り分けであり、画像ファイル自体の変換ではありません。.webpファイルは事前に用意しておきます。

【Apache】Webp画像を設定する方法

RewriteEngine On
# content-type image/webpというMIMEタイプがない場合があるので追加する
addType image/webp .webp
RewriteCond C:/MAMP/htdocs/some-folder/images/$1.webp -f
RewriteRule /?images/(.*)\.(jpe?g|png) images/$1.webp

jpe?gとすることで、eがある場合もない場合も両方にマッチします。
|は、左辺と右辺のどちらかにマッチするという条件です。
()が2つありますが、最初の方が$1で取得でき、それをsubstitutionの$1.webpと画像のファイル名に指定します。
RewriteCondのパス(上の例ではC:/MAMP/htdocs/some-folder/)は、環境ごとのドキュメントルートに置き換えます。.htaccessに書く場合は、%{DOCUMENT_ROOT}/images/$1.webpのように変数で書いておくと、本番サーバーへそのまま持っていけます。

検証ツールのnetworkタブのcontent-typeで確認できる「image/webp」という部分はMIMEタイプといいます。
このMIMEタイプが正しく返っていないと、ブラウザが中身をWebPとして解釈できず、画像が表示されない問題になります。
AddType image/webp .webpで、webp拡張子のファイルにはimage/webpを返すよう設定できます。ディレクティブ名の大文字小文字は区別されませんが、公式ドキュメントの表記はAddTypeです。
新しめのApacheや多くのレンタルサーバーでは、mime.typesにWebPが最初から登録されているため、この1行がなくてもimage/webpが返る場合があります。検証ツールでapplication/octet-streamimage/jpegになっていたときだけ追加すれば十分です。

拡張子を.webpに変えたのに画像が表示されないときは、次の順で確認します。

  • 検証ツールのResponse HeadersでContent-Typeがimage/webpになっているか(違うならAddTypeが効いていない、または.htaccessが読まれていない)
  • 書き換え先の.webpファイルが実際に同じフォルダに存在するか(RewriteCondの-fで存在確認しているため、無ければ元のjpeg/pngが返る)
  • mod_rewriteが有効で、.htaccessを使うならAllowOverrideで許可されているか
スポンサーリンク

Webp画像に対応しているブラウザとそうでないブラウザを判定する

検証ツールのnetworkタブのRequest HeadersのAcceptでは、使用ブラウザが理解できるMIMEタイプが列挙されています。
*/*が含まれていれば、どのMIMEタイプでも受け取れるという意味です。
このRequest HeadersのAcceptにimage/webpがあるかどうかで判定可能になります。

RewriteEngine On
# content-type image/webpというMIMEタイプがない場合があるので追加する
addType image/webp .webp
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond C:/MAMP/htdocs/some-folder/images/$1.webp -f
RewriteRule /?images/(.*)\.(jpe?g|png) images/$1.webp

%{HTTP_ACCEPT}でRequest HeadersのAcceptの部分を指定し、そこにimage/webpが含まれる場合だけ書き換える条件にできます。

同じURLに対してブラウザによって違う画像を返すため、レスポンスにVary: Acceptを付けておきます。これがないと、CDNやブラウザのキャッシュがWebP対応ブラウザ向けの画像を非対応ブラウザにも配ってしまい、一部の利用者だけ画像が壊れる原因になります。

<IfModule mod_headers.c>
  <FilesMatch "\.(jpe?g|png)$">
    Header append Vary Accept
  </FilesMatch>
</IfModule>

mod_headersが無効な環境では何も起きないようIfModuleで囲んでいます。

スポンサーリンク