WordPress で WebP画像をサポートする方法

前回前々回とレンタルサーバーで WebP 画像を扱うための試行錯誤の体験を紹介しましたが、ほとんどのレンタルサーバーではまだ WebP 対応は行われていませんし、 WordPress でも ver5.0 現在で対応していないので普及はもう少し先かなという感じです

但、ブラウザ側のサポートはどんどん進みモダンブラウザの8割近くがサポートされるようになってきています。WebP を使わない手はありません

ちょっと工夫すれば、今すぐにでも WebP による高速化の恩恵を受けることができるようになるので、WordPress で WebP を扱うためのひとつの手法を紹介します

JPG/PNG画像からWebP画像の複製

現時点では、まだ全てのブラウザでWebP画像が表示できるわけではないので、基本は JPG/PNG 画像です

webp-support

WebP画像を扱うときには picture タグを使い同じ画像を複数の画像形式で記述しておきます

するとブラウザ側で WebP をサポートしていればWebPを選び、サポートしていなければJPG/PNGを自動的に選んでくれるようになります

WebP複製

WordPressでは、メディアライブラリにアップロードした画像とそこから生成される大、中、サムネイル等の画像はWordPressのメタ情報としてファイル名やサイズが管理されています

そこで、画像のメタ情報の登録・更新タイミングで、JPG/PNG 画像と同名の WebP 画像がなければ同じディレクトリ上に WebPを複製する機能を Celtispack というプラグインにを設けました

同名の WebP ファイルとすることで、特別な管理データを追加しなくてもJPG/PNGのデータをベースにサイズ等のデータも共有出来て簡単にプログラムから扱うことができます

Celtispack-WebP複製設定

Celtispack の Thumbnail optimize の WebP 画像複製を有効化しておけば、JPG/PNG 画像ファイルをアップロードするごとに自動的に WebP 画像が複製されます

また、既にアップロード済みの既存の JPG/PNG ファイルから WebP を複製したい場合は、サムネイル再作成を有効化しておけば、投稿記事の編集画面を開いたり、メディアライブラリを開いたりした時の画像のメタ情報が読み出されるタイミングでまだ WebP 画像がなければ自動的に複製します

従って、サムネイル再作成とWebP画像複製の2つを有効化しておけばいつの間にか WebP 画像が複製されているということです

この複製機能は GD で WebP がサポートされているか、同胞している cwebp コマンドが実行可能な場合のみ有効となりますので、ご使用のサーバーによっては機能しない可能性もございます

※WebP画像を活用するには htaccess へリライトルールを設定する方法、picture タグを使用する方法等があります。簡単なのは、セルティスラボ製のWordPressテーマ Celtis Speedy を使うか、 Celtispack Addon (有償)に実装されている WebP対応の遅延ロードで picture タグ形式に自動的に置き換えるのがオススメです

WebPの画質について

JPGと同等の画質なら2~3割データサイズを減らせると言われている WebP ですが、cwebp で変換するときのデフォルトの画質は 75 となっています

デバッグ中に画質を変えながら作業していたのですが、WebPデフォルトの75より少し高くしたほうがきれいだったので設定から画質優先(88)、ノーマル(80)、サイズ優先(72) を選択できるようにしました

img タグからpictureタグへの変換

WordPressでWebP画像を使うには、テーマ等でWebP画像の有無を確認し、img タグから picture タグへ置き換える必要があります

picture タグのサポート状況です

picture-support

pictureタグのサンプル

WordPress 5.0 でも管理画面の WordPress について という「WordPress 5.0. へようこそ」ていうページなんかでちゃっかりとこんな感じで picture 使っています

<div class="full-width">
	<picture>
		<source type="image/webp" media="(max-width: 782px)" srcset="https://s.w.org/images/core/5.0/header/Gutenberg%20Mobile1x.webp 1x, https://s.w.org/images/core/5.0/header/Gutenberg%20Mobile.webp 2x" />
		<source media="(max-width: 782px)" srcset="https://s.w.org/images/core/5.0/header/Gutenberg%20Mobile1x.jpg 1x, https://s.w.org/images/core/5.0/header/Gutenberg%20Mobile.jpg 2x" />
		<source type="image/webp" srcset="https://s.w.org/images/core/5.0/header/Gutenberg1x.webp 1x, https://s.w.org/images/core/5.0/header/Gutenberg.webp 2x" />
		<img src="https://s.w.org/images/core/5.0/header/Gutenberg1x.jpg" srcset="https://s.w.org/images/core/5.0/header/Gutenberg1x.jpg 1x, https://s.w.org/images/core/5.0/header/Gutenberg.jpg 2x" alt="">
	</picture>
</div>

picture タグを使うには、同じ画像を JPG または PNG と WebP の2つの形式で保持しておく必要があります

従って、サムネイルもサイズ毎に同じように2つの形式で持っておく必要があり、サーバー側の容量は結構必要になってきますので注意して下さい

IEへの対応

また、picuture タグは、IEでは対応していないので lozad.js 遅延ロードを使ってIEでも問題が起きないようにします

下記のような感じで picture タグに data-iesrc を書いておけば lozad 側で対応してくれます

Example with picture tag

Create a broken picture element structure.

IE browser don’t support picture tag! You need to set data-iesrc attribute (only for your picture tags) with source for IE browser

data-alt attribute can be added to picture tag for use in alt attribute of lazy-loaded images

<!-- For an element to be caught, add a block type that is different from the inline and some min-height for correct caught into view -->
<picture class="lozad" style="display: block; min-height: 1rem" data-iesrc="images/thumbs/04.jpg" data-alt="">
    <source srcset="images/thumbs/04.jpg" media="(min-width: 1280px)">
    <source srcset="images/thumbs/05.jpg" media="(min-width: 980px)">
    <source srcset="images/thumbs/06.jpg" media="(min-width: 320px)">
    <!-- NO img element -->
    <!-- instead of img element, there will be the last source with the minimum dimensions -->
    <!-- for disabled JS you can set <noscript><img src="images/thumbs/04.jpg" alt=""></noscript> -->
</picture>

When lozad loads this picture element, it will fix it.

background-image への対応は?

画像は img タグだけでなく background-image を使っている場合があります

この場合は、picture タグが使えないので、moderizer を使いhtml 要素に加えられる webp / no-webp クラスと組み合わせた CSS により選択させるか、インラインなら遅延ロードのJavaScript を使用してWebP画像への置き換えで処理するか等が考えられます

遅延ロードでのWebP置き換えに必要な手順は以下のようになります

  1. HTML出力データ構築時にWebP画像の有無を確認して、存在する場合は background-image を使っているタグに判別用クラスを追加して JavaScript側でも画像の有無を判別できるようにします
  2. moderizer(javascript) を使いブラウザが WebP をサポートしているか判別できるようにします
  3. lozad.js 遅延ロードで、background-image を遅延ロードするときに先の2つの条件を満たしていたら画像イメージを同名の WebP を使うように置き換えるようカスタマイズします

moderizer による WebP 判別については下記サイトを参照

https://css-tricks.com/using-webp-images/

以上で background-image でも WebP 画像を使用できるようになります

あとは、ブラウザキャッシュで webp ファイルが機能するように htacess 等にjpg 等と同様に1週間以上の期限を設定しておくことで WebP に対応した高速なサイトの出来上がりです (^^)

ちなみに現時点では、WebP 対応するにはブラウザのサポートやIEへの対応もあり、遅延ロードと組み合わせるのが必須と思われるので AMP ではちょっと使うのは難しいようです


まとめ記事紹介

go-to-top