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-streamやimage/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で囲んでいます。