WEB NOTE
WEB関連の備忘録

画像の次世代フォーマット webpについて

サイト構築

WebP(ウェッピー)は、米Googleが開発しているオープンな静止画フォーマットです。
圧縮をした画像よりもさらにファイルサイズがを抑えることができます。
現在なんと、Chrome・Firefox・Edge・Operaが対応しています。
IEが対応していないのが残念ですが、対応方法もあるのでそろそろ導入することを検討するべきかなって思います。
現在、Safari、iOS14以降のiPhoneで対応したため、IE以外の主要ブラウザすべてが対応しています。

webpの対応方法

基本的に使い方は他の画像ファイルと同様にimgタグなどに直接記述するだけですが、非対応のブラウザも考慮した記述をしないといけません。
詳しくは以下に記述していますので、ご覧ください。

imgタグでの対応方法

imgタグで利用するためには大きく2種類の方法があります。pictureタグを使うか、 htaccessで制御します。
IEへの考慮、HTMLへの記述の手間を考えると、htaccessでの対応が良さそうです。

pictureタグを使う方法

htaccessを触ることのできない案件などを考えると、一番現実的な対応方法がpictureタグを使う方法です。
以下のコードで対応することができます。

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

なんで開発元からの利用を控えてって言われているIEを考慮しないといけないの? pictureタグ非対応IEに対応させるには、picturefill.js などを利用すれば大丈夫です。IEが嫌いなので使い方 (jsタグを読み込むだけ) は割愛させていただきます。

htaccessで制御する方法

htaccessを触ることのできる環境であればこちらの方法で対応するのが楽でいいかなと考えます。
制御としては「アクセスしたユーザーが WebP 対応ブラウザで、且つ WebP 画像が用意されていれば表示する」 とシンプルな方法です。

# WebP対応ブラウザかつWebPファイルがあればWebPファイルを返す設定
<IfModule mod_rewrite.c>
  # Rewriteモジュールを有効にする
  RewriteEngine On

  # WebP対応ブラウザはAcceptリクエストヘッダにimage/webpを含む慣例
  # その場合のみ後続のRewriteRuleを適用する
  RewriteCond %{HTTP_ACCEPT} image/webp

  # 対応するWebP版のファイルがある場合のみ後続のRewriteRuleを適用する
  RewriteCond %{SCRIPT_FILENAME}.webp -f

  # *.jpg、*.png、*.gifファイルを*.webpファイルに内部的にルーティングする(ルーティング先は$0.webpでも可)
  # Content-Typeはimage/webpにする
  RewriteRule .(jpe?g|png|gif)$ %{SCRIPT_FILENAME}.webp [T=image/webp]
</IfModule>

# 拡張子.webpファイルへの直接アクセスにはContent-Typeとしてimage/webpを返す設定
<IfModule mod_mime.c>
  AddType image/webp .webp
</IfModule>

# WebPファイルがあるかもしれない画像へのリクエストは全てVary: Acceptレスポンスヘッダを返す設定(CDN対策)
# Headerディレクティブ単独ではできないのでSetEnvIfディレクティブとの組み合わせで実現する
<IfModule mod_setenvif.c>
  SetEnvIf Request_URI "\.(jpe?g|png|gif)$" _image_request
</IfModule>

<IfModule mod_headers.c>
  Header append Vary Accept env=_image_request
</IfModule>

コードはこちらのサイトを参考にさせてもらいました。

こちらのコードを利用した場合、画像のファイル名に少し注意が必要です。
例えば、xxx.jpg という画像に対してのwebpファイルは xxx.jpg.webp このような名前で用意する必要があります。

background-imageでの対応方法

先ほど紹介した2つの対応方法では、背景に利用している画像までは対応しきれません。なので、background-imageも対応させるために Modernizr というJSを利用します。

Modernizrのダウンロードと使い方

公式サイトへアクセスすると、自分好みにカスタマイズしてModernizrをダウンロードすることができます。数あるオプションから「①webp」を選択し、「②BUILD」を押してダウンロードします。こちらのリンクから飛ぶと画像のような選択された状態になっています。

使い方は任意の場所に、先ほどダウンロードしたJSファイルを読み込むだけです。

<script src="modernizr-custom.js"></script>

分けるためのコードの書き方

modernizr.jsを読み込んだら、<html>に 対応しているブラウザには「webp」、非対応ブラウザには「no-webp」とクラス名が付与されます。
なので以下のようにCSSを書いて出し分ければOK。

.element {
  .webp & {
    background-image: url(xxx.webp);
  }
  .no-webp & {
    background-image: url(xxx.jpg);
  }
}

使えそうなmixin

sassファイルでサイト構築をする際にあれば便利だと思うmixinを作ったので紹介しておきます。

@mixin webp($img, $kaku: j, $page: '/') {
	@if $kaku == j {
		$kaku: jpg;
	} @else if $kaku == p {
		$kaku: png;
	} @else if $kaku == g {
		$kaku: gif;
	}

	@if $page == '/' {} @else {
		$page: '/' + $page + '/';
	}
	$path1: '../img' + $page + 'webp/' + $img + '.webp';
	$path2: '../img' + $page + $img + '.' + $kaku;

	.webp & {
		background-image: url($path1);
	}

	.no-webp & {
		background-image: url($path2);
	}
}

/* xxx.jpgの場合 */
.element { @include webp(xxx,j,フォルダパス[無ければ空白]); }

/* コンパイル */
.webp .element {
  background-image: url(xxx.webp);
}
.no-webp .element {
  background-image: url(xxx.jpg);
}

前提として、使いたい画像と同階層にフォルダ名「webp」を作成。その中に同名のwebpファイルを入れます。
以下のような感じにです。

index.html
├─ img ─ xxx.jpg
│   └ webp ─ xxx.webp
└─ css ─ style.css
    └ style.scss

webp画像の作り方

肝心のwebp画像の作り方ですが、「PNG、JPGをWEBPに変換くん」を使えばドロップアンドドラッグで簡単に作ることができます。

Photoshopは基本未対応です。webpに変換してくれる便利な AdobeWebM というプラグインがありますが、利用したことないので説明は割愛させていただきます。

遅延読み込みさせる方法

LazyIMG.js を使えば簡単に対応できます。
詳しくは「画像の遅延読み込みを簡単に実装できるIE対応の超軽量ライブラリ「LazyIMG.js」」をご覧ください。