画像やリンクが無効になっている可能性もあるのでご了承下さい。
はじめに
筆者はメインブラウザとして Firefox を使用しているが、この度 Firefox 65 にて WebP フォーマットがサポートされた為、WordPress と Web サーバ (Nginx) 側の対応も行う事とした。
画素数の大きな写真等、Jpeg フォーマットよりも大きくファイルサイズを縮小出来て良く見れば多少の劣化が見られる物のぱっと見では分かりづらい事の方が多い。
しかし、画質の劣化も十分許容出来る範囲である事から転送量削減した方がサーバサイドにもクライアントサイドにもエコかなと言う事で。
特にアイキャッチ画像なんかはサイズが小さければ小さいほどトップページのロード時間も短縮できると言う物。
使用するプラグインは EWWW Image Optimizer
EWWW Image Optimizer (以下 EWWW IO) は以前から使用していたプラグイン。
これは Jpeg 画像を最適化することで画像サイズを縮小してくれる。Jpeg ファイルの画質を示すパラメータを少し落とす感じになるので、サムネイル画像は特に画質の低下が認められる物のフルサイズの画像は違和感の無い物だったから重宝していた。
EWWW IO は Jpeg を最適化するという以外にも WebP フォーマットへの変換もサポートしている為にこれを上手いこと利用する事にする。
設定は WordPress の管理画面より 設定 以下 EWWW~ を開く。
WebP のタブをクリックして JPG, PNG から WebP の項目にチェックを入れる。
変更を保存 をクリックすると Apache の .htaccess 用設定が表示されるが筆者サーバは Nginx を使用中なので別途対応する。
Nginx の追加設定
上記 EWWW IO のドキュメントに Nginx の設定方法が掲載されているのでそのまま捻ること無く素直に設定する。
先ずは http ブロック中に次の map ディレクティブを記述。
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
ブラウザが送信した Accept ヘッダの格納される $http_accept
を評価して大文字小文字を区別せず webp がマッチした場合、変数 $webp_suffix
に “.webp” をセットする動作をする。マッチしなかった場合は WebP 非対応のブラウザとなる為に空となる。
次に /etc/nginx/mime.types を編集して MIME の追加を行う。既に記述されていた場合はそのままで。
image/webp webp;
最後に対象ホストの server ブロック内に location ディレクティブを記述する。
なるべく他の location ディレクティブよりも上位に記述した方が良い。画像ファイルに対するブラウザキャッシュの設定などよりも後に記述すると想定通りの動作をしてくれない。
location ~* ^.+\.(png|jpe?g)$ {
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
}
リクエストされた URI の末尾が大文字小文字を区別せず png, jpg, jpeg だった場合、ヘッダに Vary Accept を追加する。
EWWW IO により WebP 変換を行ってもソースファイルは残り、同一 URI にて jpg と webp の 2 つのソースが選択的に使用されるがどっちを使うか適切にコントロールする為に Accept ヘッダをキャッシュしておく。同一 URI で Content-Type が異なる事に対応するため―― という方が端的かなと。
そして try_files ディレクティブによりリクエストされた正規の URI に $webp_suffix
をくっつけた物へのアクセスを試す。この時 .webp を付けてもアクセス出来ればそのままコンテンツを返し、無いようであれば素直に URI のみを返す。それもダメなら 404 エラーを返す動作になる。
EWWW IO は WebP 変換をするとオリジナルファイルに .webp を付けるだけなので filename.jpg.webp みたいなファイル名になる。この形式に沿う形でアクセスを制御している。
ここまで設定を終えたら Nginx を再起動若しくはリロードして設定を反映させる。
動作確認
改めて EWWW IO の設定画面に入り画面を下までスクロールされると次のような表示があるハズ。
もし赤背景に PNG と書いてあればサーバサイドの対応が不十分という事になるので設定を見なおす必要がある。
EWWW IO で再最適化
EWWW IO で WebP の設定を有効としているので、今後アップロードされる画像に関しては自動で WebP フォーマットの画像が生成される。
しかし既存の画像ファイルには存在しないので改めて全ての画像ファイルに対しても WebP フォーマットの画像を生成させる為に再度最適化を実行させる必要がある。
試験的に行うのであれば比較的新しい記事で使われている画像ファイルを管理画面のメディアから手動で幾つか最適化しなおしてみるのも良いだろう。
実際の動作
まずは今回の設定を行う前のとあるサムネイル画像 20190102-DSC_0019-600x399.jpg の転送具合を示す。
本記事で行った設定後の同一画像の転送はこうなった。
設定前は当然 jpg ファイルそのままの 85,067 バイトが転送されたが、設定後は表示上こそ jpg となる URI のままだが実際に転送された物は WebP フォーマットのデータにすり替わり 63,888 バイトの転送となった。
実に jpg フォーマット比約 25% の転送量削減となった。サムネイル画像という小さい物である為、劣化していようと良く分からないので全く気にならないクオリティだった。
更にオリジナルサイズ画像へのアクセスログを抜粋。
ログの 2 行目最後の部分が転送したデータサイズを示す。
WebP 非対応な Internet Explorer からアクセスすると jpg フォーマットでコンテンツが返される。
xxx.xxx.xxx.xxx - - [30/Jan/2019:16:14:41 +0900]
GET /wp-content/uploads/2019/01/20190102-DSC_0019.jpg HTTP/2.0" 200 484144
"-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
でもって以前より WebP 対応な Chrome でアクセスすると WebP フォーマットのコンテンツが返される事が分かる。
xxx.xxx.xxx.xxx - - [30/Jan/2019:16:14:55 +0900]
GET /wp-content/uploads/2019/01/20190102-DSC_0019.jpg HTTP/2.0" 200 210646
"-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
オリジナルサイズが 1200x798 で 484,144 バイトと大きめな事もあり WebP フォーマットになると半分以下の 210,646 バイトにまで縮小された。結構すごい。
おわりに
画像の数が多いと再最適化に掛かる時間もあるしストレージの使用量も増えてしまうかも知れないが、画像の転送量というユーザサイドへの負担も大きい部分だけに極力削減したいのでストレージ使用量が増えてしまうのはこの際だから気にしないようにする。
今まで以上に少しでも快適に閲覧できるサイトになる様な仕組みとして WebP フォーマット画像対応化というのは良い手段であるかなと思う。
今回は Firefox が WebP 対応した事を機に設定を行ってみたが、WebP 非対応なブラウザにも上手いこと考慮された仕組みであったことからもう少し早めにやっておいても良かったなとも思ってみたり。
その後
この記事を書いてから当ブログ全画像の強制最適化を実行していた。オリジナルに対して生成されたサムネイルを含めて行われるので、ファイル数としては大体 7 万ファイルほどが対象に。
jpg/png だったファイルそれぞれに WebP フォーマットの画像が追加生成される為、最終的なファイル数は 11 万程に増えてストレージ容量は大体 1.2GB 増という結果となった。
処理完了後に Firefox 65 にてトップページをスーパーリロードしてみたところ、アイキャッチ画像など自ホスト発の画像に関しては全て WebP フォーマットに切り替わっていた。
そして IE など WebP 非対応ブラウザからのアクセスでは今まで通り Jpeg, PNG フォーマットによるコンテンツが返されていることを確認出来た。
これにより互換性を保ちつつ WebP フォーマット対応ブラウザからのアクセスに於いては効率良く画像の転送が可能になったこととなる。
目標とする動作が割と簡単にできたので良かった。
- 2019/01/31 8:10 — その後の項を追記した
コメント