WebP(ウェッピー)対応はじめました！実装例とカンタン一括変換する方法

暑過ぎる夏到来！ということで冷やし中華はじめまし… 
ではなく、WebP対応はじめました。暑さ関係なし。

## WebPなんぞや？
- Google開発のオープンな静止画フォーマット。ファイル拡張子「**.webp**」
- Googleが使用を推奨。**データ容量がほかの画像フォーマットより軽い** **(圧縮率が高い)**というメリットがある -> 軽量化・高速化に寄与
- 可逆圧縮なら**PNG画像と比べてサイズが26％小さく**なり、非可逆圧縮なら**JPG画像より25〜34％小さくなる**らしい。JPG / PNG / GIF (アニメーション含む)に対しての代替となる

### WebP小話
- 読み方は「**ウェッピー**」。「チャッピー」「ヒッピー」「ホッピー」「ポリッピー」に語感が似ており何か**ファンシーな響き**。声に出して読みたい画像フォーマット
- 単語の頭と尾が大文字である。たくさんの人が語尾をうっかり小文字にしちゃうヤツだこれ…
- けっこう古い (2010年に仕様公表)

## ブラウザ対応状況を考慮した実装 (2019/8現在)
- WebPは**Google Chrome、Microsoft Edge、Firefoxで使用可**。Apple Safariはそっぽ向いてる。IEはお察しください (泣)
- 日本だと約45%のユーザーが利用可能で増加傾向にある (世界全体では80.53%)

　参考：https://caniuse.com/#search=webp

### 実装例
- 方針：**対応ブラウザではWebPを表示し、対応していないSafariとIE11ではJPG / PNG等を表示([フォールバック](http://e-words.jp/w/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%AB%E3%83%90%E3%83%83%E3%82%AF.html))する**
  - `picture`要素を用いることで、対応状況に合わせた画像(形式)の出し分けが可能
  - IE11で`picture`要素を使うために「[Picturefill](https://scottjehl.github.io/picturefill/)」JSライブラリを泣く泣く導入

```HTML:HTML
<picture>
  <source type="image/webp" srcset="img/image.webp, img/image@2x.webp 2x"> <!-- WebP対応ブラウザはsourceを適用 -->
  <img src="img/image.png" alt="画像代替テキスト"> <!-- WebP非対応ブラウザはimg画像を表示 -->
</picture>
```
以下はIE11対応。webpack + babelなどでES5へのトランスパイルが必要

```JavaScript:JavaScript
import picturefill from "picturefill";
picturefill();
```
または

```HTML:HTML
<head>
  ～
  <script src="/picturefill.js"></script>
</head>
```

- アイコン、ロゴ、簡単なイラストなど**ベクター画像はSVG**、写真とかそれ以外の**ラスター画像はWebP** (JPG / PNGの代替)という得意分野で使い分けたい

## WebPの作成・変換方法

### [Windows編] 「WebPconv」デスクトップアプリで一括変換
- Windowsのみ対応の無料デスクトップアプリ「**WebPconv**」を利用する。[公式サイト](http://www.romeolight.com/ja/products/webpconv/)の右サイドバーにある「Download Now」からPCへダウンロード
  - Windows10でWindows Flamework 3.5関連のダウンロードエラーが出たら有効化して再トライ  
-> https://blogs.technet.microsoft.com/askcorejp/2018/10/05/enable_net35_win10/
- インストールが完了したら「WebPconv」を起動する。下のアプリUI画像の「+」ボタン押下で開くエクスプローラーからローカルディレクトリ+ファイルを選択(複数選択可) → 右のボタン押下で一括変換実行  
<img width="598" alt="WebPconvの操作画面(UI)、+ボタンとその真横のアイコンボタンに赤枠で操作対象を明示" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97066/0f227f58-e84b-d189-36d3-ede86e11aebf.jpeg">

### [mac編] Homebrewで「cwebp」をインストール。シェルスクリプトで一括変換処理
- macの場合はコマンド(ターミナル)でWebPへ一括変換処理する。黒い画面アレルギーの人スマソ…
- 「**cwebp**」というエンコーダー(WebP変換)ツールを[Homebrew](https://qiita.com/omega999/items/6f65217b81ad3fffe7e6)経由でインストール

```console:CLIでインストール
brew install webp
```
```console:シェルスクリプトで一括変換(ループ処理)
# cdコマンドで対象画像ファイルのあるディレクトリへ
for file in *; do cwebp "$file" -o "${file%.*}.webp"; done
```

### そのほかのWebP作成・変換ツール(単一処理)
- Adobe Photoshop CCに「AdobeWebM」プラグイン(Win/mac対応)を導入することで、WebPの読み込みや書き出しが可能に -> http://www.fnordware.com/WebM/
 - ダウンロードしたら、ローカルのPhotoshop関連保存場所にある「Plug-ins」ディレクトリ直下に格納すると使用可能

- Webサービス：[WEBP変換ツール (jpg、pngとwebpを相互変換) | Syncer](https://lab.syncer.jp/Tool/Webp-Converter/)
- Webサービス：[Squoosh](https://squoosh.app/)

## プラスで表示高速化にチャレンジ
### リソースを先読みする
- ファーストビューに比較的大きめの画像(ヒーロー画像、メインビジュアルなど)が存在する場合、当該画像を`link rel="preload"`で先読み指定して、初期画面表示の高速化を試みる
- 他にもさまざまなコンテンツを先読みできる。適切に使いたい  
-> https://developer.mozilla.org/ja/docs/Web/HTML/Preloading_content

```HTML:HTML
<head>
  ~
  <link rel="preload" href="img/hero.webp" as="image">
  ~
</head>
```
### 画像を非同期デコードして表示高速化
すべての画像を`img decoding="async"`で非同期読み込みし、順番待ちをなくして表示高速化を試みる

```HTML:HTML
<body>
  ~
  <img decoding="async" src="img/photo1.webp">
  <img decoding="async" src="img/photo2.webp">
  ...
```
※ ~~ズッコケ~~豆情報：Chrome76(75?)で実装予定と噂された`loading`属性(`loading="lazy"`・Lazy Load)~~は現状実装されていない~~ → 後日、76で追加実装された模様 (2019/8/15記)

- https://chromestatus.com/feature/5645767347798016
- https://web.dev/native-lazy-loading

### パフォーマンス検証結果
A. JPGのみ
B. WebPのみ
C. WebP + `link rel="preload"` + `img decoding="async"`

上記パターンでサーバーアップし、1画面あたり20枚の画像を10回読み込み、Chrome DevToolsで中央値を取る形で検証したが、読み込み速度(load)にあまり有意な差は認められなかった。ページ容量は「A > B = C」。
理論上読み込み速度は「C < B < A」となるはずなので、いずれもっと厳密な条件で検証をしてみたい。

では。

## 参考記事
- [A new image format for the Web | WebP | Google Developers](https://developers.google.com/speed/webp/)
- [cwebp | WebP | Google Developers](https://developers.google.com/speed/webp/docs/cwebp)
- [サイト高速化に必須の link rel=preload とは？（使い方とサンプルHTML・CSS） - ウェブ企画ラボ](https://webkikaku.co.jp/blog/htmlcss/preload/)
- [Webパフォーマンスの振り返り 2018 - Webパフォーマンスについて](http://takehora.hatenadiary.jp/entry/2018/12/07/055454)