Pagespeed Insightsで「次世代フォーマットでの画像の配信」を指摘されました。
改善策はJPGやPNGに代わり、WEBPでの配信。
検索して出てきたのはプラグインEWWW image optimizer使った方法ばかりでした。
しかしもっと調べてみたところ、NginxならプラグインがなくともWEBPの一括変換・自動変換・配信の全てに対応できることがわかりました。
KUSANAGI(Nginx)で実際にやってみたので、その方法について記します。
アイキャッチの画像はKUSANAGIのイメージキャラクター草薙沙耶 ©PRIME STRATEGY
はじめに KUSANAGIを個人利用している方へ
KUSANAGIを個人利用している方でサーバースペックに余裕があるならWEXALの導入を勧めます。
本稿の内容は全てWEXALが自動でやってくれます。
個人利用であればWEXALは無料です。
本稿の主旨
本稿では、KUSANAGI(Nginx)でWEBPの変換・配信する方法を説明します。
変換については既存のファイルをwebpに一括で変換し、なおかつ加わったファイルも自動でwebpに変換します。
EWWW image optimizerを使った方法なら幾らでも出てきます。
しかし本稿の方法ですと、プラグインは一切必要ありません
「KUSANAGI WEBP」で検索してみたら「EWWW image optimizerを使って」ばかりでした。
しかし一方で「Nginxならプラグインなくても簡単にできる」とも出てくる。
「この差はどうして?」と思ったので、実際にKUSANAGIでWEBP画像の変換&配信をEWWW image optimizer無しで導入してみた次第です。
本稿の方法におけるメリットは、
- WEBP変換プラグインを1つ減らせること
- WEBP変換を画像登録より後で行うので登録時の重さが解消できること
ただし2はWEBPが即座に反映されない点でデメリットでもあります。
30分ほどのタイムラグをどう捉えるかですね。
始める前に KUSANAGIの画像最適化機能について
KUSANAGIの画像最適化機能は、他のWordPressプラグインと比べて、全く劣りません。
検証した記事がこちら。
jpgについては完全に同等。
pngについては可逆圧縮か非可逆圧縮の差じゃないかと思います。
私はこれで足りるので他の画像最適化系プラグインは使っていません。
KUSANAGIで既存の画像ファイルを一括でWEBPに変換する
こちらの記事を参考にして進めます。
1 cwebpをインストールする
KUSANAGIにはデフォルトで入ってないのでインストールします。
(もし入っていて、私が気づかなかっただけならごめんなさい)
次のページにアクセスします。
私は「libwebp-1.1.0-rc2-linux- x86-64.tar.gz」をダウンロードしました。
これで動いたので参考にしてください。
ローカルで解凍して、binフォルダに入っているファイル群を「/usr/local/bin」にアップします。
gzip対応の解凍ソフトは予め御用意ください。
私はLhaForgeを使っています。
2 シェルスクリプトを作成する
ローカルで新規テキストファイルを作成します。
ファイルの中身は、次のように書きます。
#!/bin/bash DIR="DIR="/home/(自分の環境に応じたパスを記す)/DocumentRoot/wp-content/uploads/20??/*" # 対象ディレクトリパス(要変更) JPEG_CWEBP_OPTS="-q 75 -m 4" # Jpeg向け非可逆cwebpオプション PNG_CWEBP_OPTS="-lossless" # PNG向け可逆cwebpオプション CWEBP="/usr/local/bin/cwebp" # cwebpコマンドをインストールした場所、1の通りにしたならこのままで cd $(dirname $0) shopt -s nocasematch find $DIR -type f -regextype posix-extended -iregex ".*\.(jpe?g|png)$" -print0 | \ while IFS= read -r -d '' SRC; do WEBP="$SRC.webp" if [[ ! -e $WEBP || $SRC -nt $WEBP ]]; then if [[ $SRC =~ \.jpe?g$ ]]; then echo "Convert to lossy WebP: $SRC" "$CWEBP" $JPEG_CWEBP_OPTS "$SRC" -o "$WEBP" elif [[ $SRC =~ \.png$ ]]; then echo "Convert to lossless WebP: $SRC" "$CWEBP" $PNG_CWEBP_OPTS "$SRC" -o "$WEBP" fi fi done
「webp.sh」という名前で保存します。
jpgの圧縮率はデフォルトで75。
特にいじる必要はないと思います。
画像ファイルは年月でフォルダわけをしている場合を念頭においてます。
「20??」の「?」は「任意の1文字」
この場合は「2020など頭に20がついたフォルダ」を指します。
「*」は「任意の文字数の任意の文字」。
この場合は「2019や2020フォルダの直下にある全てのフォルダ」となります。
この点は絶対に注意してください。
②は見落としがちです。
もし忘れると、
WEBPの自動変換ができない!
シェルスクリプト動かそうとしても「webp.shなんてファイルはない」って怒られる!
これで数時間無駄にしました。
その他のオプションについてはこちらを御覧ください。
3 webp.shをアップロードする
プロファイル直下にshフォルダを作って、その中に入れます。
/home/kusanagi/【プロファイル名】/sh
アップしたら実行権を与えます。
黒い画面で次のコマンドを打ち込みます。
# chmod a+x /(入れたパス)/webp.sh
4 既存の画像ファイルをWEBPへ一括変換する
ログインして、黒い画面に次の通り入力します。
# cd /home/kusanagi/【プロファイル名】/sh # ./webp.sh
うまくいっていれば、すごい勢いで変換が始まります。
終わるまでには少々時間が掛かります。
終わったらフォルダを開いてみてください。
webpファイルができあがっているはずです。
なお、この作業は、シェルスクリプトの動作確認も兼ねています。
KUSANAGIで追加した画像ファイルをWEBPに自動変換する
webp.shをcronに登録して自動実行させます。
KUSANAGI8の場合は/etc/crontab。
KUSANAGI9の場合は/var/spool/cron/root
などを開きます。
(「など」というのは複数設定ファイルが複数あるのでどれでもいいという意味です)
*/30 * * * * (ユーザー名) /home/kusanagi/【プロファイル名】/sh/webp.sh >>/home/(自分のWordPress環境のパス)/uploads/webp.log 2>&1
保存して、
# kusanagi restart
webp.shは自分の入れたパス名に変更してください。
私と同じならこのままでOKです。
ユーザー名は、例えばkusanagiなど。
30は「30分ごとに自動実行する」設定です。
最初は10分程度に設定してみて、10分経過したらuploadsフォルダにログファイルがあるか確認してください。
さらに中身をチェックしてみてください。
正常なログが吐き出されていれば自動実行されています。
もしログファイルがなければ、あるいはおかしければ、cronの動作のログをチェックします。
/var/log/cronを開いてみてください。
シェルスクリプトが動作しない手掛かりが記されているはずです。
KUSANAGIでwebpを自動配信する
これらの記事を参考に進めました。
両方読んだ方がわかりやすいと思います。
次のファイルを開きます。
KUSANAGI8の場合、
/etc/nginx/conf.d/(プロファイル名)ssl.conf
KUSANAGI9の場合、
/etc/opt/kusanagi/nginx/conf.d/(プロファイル名).conf
一番上に、次の記述をします。
map $http_accept $webp_suffix { default ""; "~*webp" ".webp"; }
server{}内の「error_log(略)」と書かれた行と「 charset UTF-8;」と書かれた行の間に次の記述します。
location ~* \.(png|jpe?g)$ { # VaryヘッダとしてAcceptを返す add_header Vary Accept; # WebP対応ブラウザでは、image.jpg.web、image.jpgを探索 # 非対応のブラウザでは、image.jpg、image.jpgを探索 # いずれもない場合は404を返す try_files $uri$webp_suffix $uri =404; }
保存して、
# kusanagi restart
実際にwebp配信がされているかチェックします。
Chromeでサイトを開いてF12でデベロッパーツールを起動→ctrl+F5キーで更新します。
変換前
赤で囲んだ画像が新しくメディアライブラリに入れた画像です。
30分後。
一見するとjpgで配信されているかに見えます。
しかしwebpで配信されていることはサイズでわかります。
78.9kb→31.7kbと半分以下になっています。
この例ですと、webp対応のブラウザなら「conoha3m1.jpg.webp」を配信、そうでなければ「conoha3m1.jpg」を配信。だけどコンテンツは「conoha3m1.jpg」のままとなります。
一言で「仕様」。
この点がEWWWを使った場合とは異なります。
EWWWを使った場合は、コンテンツも「hoge.jpg.webp」に変わっています。
まとめ
本稿を書いた時は、まだWEXALがありませんでした。
なので現在でしたらWEXAL導入を勧めます。
ただNginxだけどKUSANAGIじゃなかったり。
法人利用だったり。
そういった方には、ぜひ実装をおすすめします。
元の紹介記事を初心者が読んでやろうとすれば、まずどこかで躓きます
私も躓きました。
だけど本稿を読みながらならスムーズにできるはず!
頑張ってチャレンジしてみてください!