サイトからのおしらせ(クリックで一覧)

KUSANAGI(Nginx)でWEBP自動変換&配信に対応する(プラグイン無し、初心者でもできます!)

この記事は約9分で読めます。

質問者の写真

Pagespeed Insightsで「次世代フォーマットでの画像の配信」に対応しろって怒られちゃった……
 
解答者の写真
あらあら
だったらWEBPで配信すればいいじゃない
 

質問者の写真

でもWEBP配信ってプラグインいるんじゃないの?
検索してみても出てくるのはEWWW image optimizer使った方法ばかり
せっかくKUSANAGIは画像最適化機能ついてるのに、同じ機能のプラグイン入れるなんて嫌だよ……
 
解答者の写真
大丈夫!
KUSANAGI(Nginx)ならEWWW無くてもWEBPの一括変換・自動変換・配信の全てに対応できるわ!
 

本稿の主旨

本稿では、KUSANAGI(Nginx)でWEBPの変換・配信する方法を説明します。
変換については既存のファイルをwebpに一括で変換し、なおかつ加わったファイルも自動でwebpに変換します。

EWWW image optimizerを使った方法なら幾らでも出てきますが、プラグインは一切必要ありません
ここが本稿最大のポイントです。
「KUSANAGI WEBP」で検索してみたら「EWWWを使って」ばかりでした。
しかし一方で「Nginxならプラグインなくても簡単にできる」とも出てくる。
「この差はどうして?」と思ったので、KUSANAGIでWEBPをEWWW無しで導入してみた次第です。

つまり導入方法そのものは、既に他でも記されています。
初心者が実装するには理解できないだけで。
ただし私も、

質問者の写真

黒い画面って美味しいの?
 

という次元の人間。
私ができたのですから誰でもできます。
躓きそうな(というか実際に躓いた)ポイントを併せて記します。
その分だけわかりやすいのではないかと。

解答者の写真
なお、わかる人には本当に簡単です
わからない人でも、やり終えたらわかります
 

始める前に 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」という名前で保存します。

画像ファイルは年月でフォルダわけをしている場合を念頭においてます。

「20??」の「?」は「任意の1文字」

この場合は「2020など頭に20がついたフォルダ」を指します。

「*」は「任意の文字数の任意の文字」。

この場合は「2019や2020フォルダの直下にある全てのフォルダ」となります。

解答者の写真
ここで絶対に抑えて欲しいポイントがあります
①UTF-8にすること、②改行方式は「LF」にすること
 

①は注意していても②は見落としがちです。
もし②を忘れるとどうなるか。

質問者の写真

WEBPの自動変換ができない!
シェルスクリプト動かそうとしても「webp.shなんてファイルはない」って怒られる!
 

私、これで数時間無駄にしました。

参考記事はこちら。

3 webp.shをアップロードする

場所は多分どこでもいいとは思うのですが。
私は先程と同じ「/usr/local/bin」に入れました。
(2でハマった原因がわからず、一番確実に動きそうなところへ移動した結果です)

アップしたら実行権を与えます。
黒い画面で次のコマンドを打ち込みます。

# chmod a+x /(入れたパス)/webp.sh

4 既存の画像ファイルをWEBPへ一括変換する

ログインして、黒い画面に次の通り入力します。

# cd /usr/local/bin
# ./webp.sh

うまくいっていれば、すごい勢いで変換が始まります。
終わるまでには少々時間が掛かります。
終わったらフォルダを開いてみてください。
webpファイルができあがっているはずです。

解答者の写真
名前は「~.jpg.webp」や「~png.webp」など「元の拡張子+webp」となります
 

なお、この作業は、シェルスクリプトの動作確認も兼ねています。

KUSANAGIで追加した画像ファイルをWEBPに自動変換する

webp.shをcronに登録して自動実行させます。

/etc/crontabを開きます。
一番下に、次の追記をします。

*/30 * * * * root /usr/local/bin/webp.sh >>/home/(自分のWordPress環境のパス)/uploads/webp.log 2>&1

保存して、

# kusanagi restart

webp.shは自分の入れたパス名に変更してください。
私と同じならこのままでOKです。

元記事にrootの記述はありませんが、私の環境ではrootを付けないと動きませんでした。

30は「30分ごとに自動実行する」設定です。

最初は10分程度に設定してみて、10分経過したらuploadsフォルダにログファイルがあるか確認してください。
さらに中身をチェックしてみてください。
正常なログが吐き出されていれば自動実行されています。

もしログファイルがなければ、あるいはおかしければ、cronの動作のログをチェックします。
/var/log/cronを開いてみてください。

どちらかのログにシェルスクリプトが動作しない手掛かりが記されているはずです。

KUSANAGIでwebpを自動配信する

これらの記事を参考に進めました。
両方読んだ方がわかりやすいと思います。

/etc/nginx/conf.d/(プロファイル名)ssl.confを開きます。
(SSL化しているはずですので)

一番上に、次の記述をします。

map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
解答者の写真
server{}の外に記述というのが大事なポイントです
 

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分後。

解答者の写真
Typeが「webp」に変わっていればOKです
 

ファイル名は同じまま。
一見するとjpgで配信されているかに見えます。

しかしwebpで配信されていることはサイズでわかります。
78.9kb→31.7kbと半分以下になっています。

解答者の写真
ファイル名が同じなのは「コンテンツを変えずに配信するファイルだけを変える」から
この例ですと、webp対応のブラウザなら「conoha3m1.jpg.webp」を配信、そうでなければ「conoha3m1.jpg」を配信。だけどコンテンツは「conoha3m1.jpg」のままとなります。
 

一言で「仕様」。
この点がEWWWを使った場合とは異なります。
EWWWを使った場合は、コンテンツも「hoge.jpg.webp」に変わっています。

コンテンツもプラグイン無しでwebpに変更する方法もあるらしいですが、本稿では割愛します。

まとめ

解答者の写真
元の紹介記事を初心者が読んでやろうとすれば、まずどこかで躓きます
著者も躓きました
しかし本稿を読みながらならスムーズに実装できるはず
頑張ってチャレンジしてみてください!
 
この記事を書いた人:天満川 鈴

広島市内のパチンコホール勤務。
3号機時代からのパチンカス。

ADHD、精神障害者手帳3級所持。

慶應義塾大学商学部→国家一種経済職→公安調査庁。
在職時は国際テロ、北朝鮮を担当。

「小説家になろう」の底辺作者。
朝鮮総聯へのスパイ工作を描いた小説「キノコ煮込みに秘密のスパイスを」はアマチュア小説ながら週刊誌報道され、話題となった。