WebP 画像を使用する

Katie Hempenius
Katie Hempenius

検討すべき理由

WebP 画像は、JPEG や PNG の画像よりも小さく、通常はファイルサイズが 25 ~ 35% 程度小さくなります。これにより、ページサイズが小さくなり、パフォーマンスが向上します。

  • YouTube では、WebP サムネイルに切り替えることで、ページの読み込みが 10% 速くなったことがわかりました。
  • Facebook は WebP の使用に切り替えた結果、JPEG のファイルサイズが 25 ~ 35%、PNG のファイルサイズが 80% 削減されました

WebP は、JPEG、PNG、GIF の画像に代わる優れた形式です。さらに、WebP は可逆圧縮と非可逆圧縮の両方をサポートしています。ロスレス圧縮では、データが失われることはありません。非可逆圧縮ではファイルサイズが小さくなりますが、画質が低下する可能性があります。

画像を WebP に変換する

通常、画像を WebP に変換するには、cwebp コマンドライン ツールまたは Imagemin WebP プラグイン(npm パッケージ)のいずれかを使用します。プロジェクトでビルド スクリプトまたはビルドツール(Webpack や Gulp など)を使用している場合は、通常、Imagemin WebP プラグインが最適です。一方、CLI は、小規模なプロジェクトや、画像を 1 回だけ変換する必要がある場合に適しています。

画像を WebP に変換するときには、さまざまな圧縮設定を指定できますが、ほとんどのユーザーは品質設定のみを気にする必要があります。品質レベルは 0(最悪)~ 100(最良)の範囲で指定できます。必要に応じて、画像の品質とファイルサイズのバランスが取れたレベルを見つけてください。

cwebp

cwebp のデフォルトの圧縮設定を使用して、1 つのファイルを変換します。

cwebp images/flower.jpg -o images/flower.webp

品質レベル 50 を使用して 1 つのファイルを変換します。

cwebp -q 50 images/flower.jpg -o images/flower.webp

ディレクトリ内のすべてのファイルを変換します。

for file in images/*; do cwebp "$file" -o "${file%.*}.webp"; done

Imagemin を使用する

Imagemin WebP プラグインは、単独で使用することも、お気に入りのビルドツール(Webpack、Gulp、Grunt など)と組み合わせて使用することもできます。通常、ビルド スクリプトまたはビルドツールの構成ファイルに 10 行程度のコードを追加します。WebpackGulpGrunt でこれを行う方法の例を次に示します。

これらのビルドツールのいずれも使用していない場合は、Imagemin を単独で Node スクリプトとして使用できます。このスクリプトは、images ディレクトリ内のファイルを変換し、compressed_images ディレクトリに保存します。

const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp');

imagemin(['images/*'], {
  destination: 'compressed_images',
  plugins: [imageminWebp({quality: 50})]
}).then(() => {
  console.log('Done!');
});

WebP 画像を配信する

サイトが WebP 対応のブラウザのみをサポートしている場合は、この記事の続きを読む必要はありません。それ以外の場合は、新しいブラウザには WebP を、古いブラウザにはフォールバック画像を配信します。

変換前:

<img src="flower.jpg" alt="">

変換後:

<picture>
  <source type="image/webp" srcset="flower.webp">
  <source type="image/jpeg" srcset="flower.jpg">
  <img src="flower.jpg" alt="">
</picture>

<picture><source><img> タグは、相互の順序付け方法を含め、すべて相互に作用してこの最終結果を実現します。

<picture>

<picture> タグは、0 個以上の <source> タグと 1 つの <img> タグのラッパーを提供します。

<source>

<source> タグはメディア リソースを指定します。

ブラウザは、サポートされている形式でリストされている最初のソースを使用します。ブラウザが <source> タグに記載されている形式をサポートしていない場合は、<img> タグで指定された画像の読み込みにフォールバックします。

<img>

<img> タグは、<picture> タグをサポートしていないブラウザでこのコードを機能させるものです。ブラウザが <picture> タグをサポートしていない場合、サポートしていないタグは無視されます。したがって、<img src="flower.jpg" alt=""> タグのみを「認識」し、その画像を読み込みます。

HTTP Accept ヘッダーの読み取り

リクエストを書き換えることができるアプリケーション バックエンドまたはウェブサーバーがある場合は、HTTP Accept ヘッダーの値を読み取ることができます。このヘッダーには、サポートされている代替の画像形式が宣伝されます。

Accept: image/webp,image/svg+xml,image/*,*/*;q=0.8

このリクエスト ヘッダーを読み取り、その内容に基づいてレスポンスを書き換えることで、画像マークアップを簡素化できます。ソースが多いと、<picture> マークアップがかなり長くなることがあります。WebP の代替ファイルを配信できる Apache mod_rewrite ルールは次のとおりです。

RewriteEngine On
RewriteCond %{HTTP:Accept} image/webp [NC]
RewriteCond %{HTTP:Content-Disposition} !attachment [NC]
RewriteCond %{DOCUMENT_ROOT}/$1.webp -f [NC]
RewriteRule (.+)\.(png|jpe?g)$ $1.webp [T=image/webp,L]

この方法を使用する場合は、HTTP Vary レスポンス ヘッダーを設定して、Accept ヘッダーに応じて画像が異なる方法で配信される可能性があることをキャッシュに認識させる必要があります。

<FilesMatch ".(jpe?g|png)$">
  <IfModule mod_headers.c>
    Header set Vary "Accept"
  </IfModule>
</FilesMatch>

前の書き換えルールでは、リクエストされた JPEG または PNG 画像の WebP バージョンが検索されます。WebP の代替が見つかった場合は、適切な Content-Type ヘッダーとともに配信されます。これにより、次のような画像マークアップを使用して、WebP を自動的にサポートできます。

<img src="flower-320w.jpg" srcset="flower-320w.jpg 320w, flower-640w.jpg 640w, flower-960w.jpg 960w">

WebP の使用状況を確認する

Lighthouse を使用すると、サイト上のすべての画像が WebP を使用して配信されていることを確認できます。Lighthouse パフォーマンス チェック([Lighthouse] > [Options] > [Performance])を実行し、次世代形式で画像を提供するチェックの結果を確認します。Lighthouse には、WebP で配信されていない画像が一覧表示されます。