あなたのサイトのjpeg画像は過剰品質である。多分。

## はじめに

Webサイト掲載用のjpeg画像の品質設定を絞り込むためのツールを作りました。

[imagemin-parameter-report](https://github.com/MasatoMakino/imagemin-parameter-report)

また、ツールの動作イメージを掴むためにデモページを用意しました。とりあえず触ってみてください。

[Demoページ](https://makino-design-staging.s3.amazonaws.com/imagemin-reporter-demo/index.html)

![](https://www.evernote.com/l/AAnpE1c90QdMsqrpvRJXCceuOhqkw2WvRnYB/image.jpg)

この記事は、このツールとその使い方、そしてチェックシートを利用して、WEBサイト構築の初期段階でjpegの品質設定を絞り込む手法を共有するためのものです。

なお、このリポートツールで扱うのはあくまでWebサイトに掲載する一般的な画像です。また、作業の最終目的はサイトの高速化です。

## jpegの品質問題

画像ファイルはWebサイトの総転送量と表示時間に非常に大きな影響を与えます。しかし、jpegの品質設定を詰める作業は以下の理由で難しくなります。

### 人手が足りない

jpegの品質設定はプロジェクトのなるべく早いうちに決めるべきです。少なくともプロダクトの実装が始まる前の段階で決めないと、立ち上がってしまったワークフローと衝突し、導入や変更がどんどん難しくなります。
しかし、プロジェクトの初期段階では、その他の問題も山積しています。メンバーの時間が捻出できないため、この問題の優先度は低くなりがちです。

### 問題意識の共有が難しい

Webサイトの構築は、多くのメンバーが関わるプロジェクトです。それぞれの立場と責任、技術と知識によって問題に対する意見が変わってきます。
たとえばデザイナーは、画質を極力高く設定したがります。また、感覚的に品質設定を決めてしまいがちなので、他のメンバーに対して設定の根拠を説明しづらくなります。エンジニアは専門知識をもっていますが、画質の設定が正しいのかをビジネス的、デザイン的な側面から判断しにくいです。マネージャーは技術的にどのような選択肢があるのかを一覧する方法を知りたがっています。

結果として労力が割けないまま、jpegの画質設定は安全側、なるべく高品質にということに落ち着く場合が多くなります。そのため過剰な品質のjpeg画像がサイト全体の表示速度を低下させます。

以上の問題から

* 労力をかけずに
* メンバー全員が結果を一覧、共有できる

jpeg画像の品質設定リポートツールが必要だと考えました。

## 使い方

というわけでリポートツールを作ってみました。

[imagemin-parameter-report](https://github.com/MasatoMakino/imagemin-parameter-report)

ここからはこのツールの使い方の解説になります。

### サンプル画像の収集

ツールの中に画像ファイルは含まれていませんので、まずは品質設定のサンプルとなる画像を収集します。デザインの作業が先行している場合はその素材を利用します。なるべく最終的なサイトに利用されそうな傾向の画像を、実際の画素数に近いサイズで揃えると判断の精度が高くなります。

今回の記事では[風のおひるね](http://kazenoohirune.net/photo/index.html)様の写真を利用させていただきました。ありがとうございます。
この記事は圧縮効果がわかりやすいように、おおよそ3000pxでご提供いただいている画像をPhotoshopで長辺1600pxにリサイズ、「書き出し」メニューで品質100に設定して出力した画像をサンプルとして使用しています。jpegの圧縮ノイズがほぼゼロの高画質画像から、徐々に品質を詰めていくためです。


### インストール

このツールは、以下の環境を前提としています。

* node.js v8.11.3
* Google Chrome v68.0.3440.106
* macOS 10.13.6
* Windows 10 1703

比較対象としてwebPを使用しているため、safariやEdgeでは正常に表示できない画像があります。
node.jsがインストールされていない環境では動作しません。事前に[インストール](https://nodejs.org/ja/)をお願いします。

1. [imagemin-parameter-report](https://github.com/MasatoMakino/imagemin-parameter-report)のリポジトリから、ツール一式をローカルへクローンしてください。
1. ターミナルで```npm install```もしくは```yarn```を実行して、依存パッケージを取得してください。
2. ```src/img/jpg_photo/```フォルダー以下に収集したサンプル画像をコピーしてください。サブディレクトリを使用しても正常に動作します。現状ではjpegのみに対応しています。
3. ```npm run publish```コマンドを実行してください。画像の圧縮をひたすら繰り返すので、このステップは時間がかかります。手元の環境では30MB20枚のサンプル画像で180秒ほどかかりました。
4. 圧縮が終了すると、ローカルサーバーが立ち上がります。http://localhost:5000 にブラウザでアクセスすると、リポートページが表示されます。生成されたファイルは```dist```フォルダーに出力されます。

### 確認

このリポートツールは大きく2つ

* 容量チャート
* 画質比較

のパートで構成されています。

#### 容量チャートの確認

![](https://www.evernote.com/l/AAnjXLyjcS1JOo_cv_mCVWn-9ib-t2ON-lkB/image.jpg)

容量チャートは、品質設定と画像サイズを比較したものになります。
サンプル画像のオリジナルサイズを1とした場合の、サイズの変化を表しています。
下部のメニューから「使用したエンコーダーのフィルタリング」と「縦軸の対数スケール化」の操作が行えます。

このチャートからはどのjpegエンコーダーでも共通する傾向が読み取れます。

1. 品質80前後までは急激に容量が削減される。
1. その後も品質設定を落とせば、その分ファイル容量は減り続ける。
2. 圧縮が効きやすい画像と効きにくい画像で二分される。どのエンコーダーでも大まかに2本の線に集まる。

傾向2に関しては、線形スケール表示で品質設定70以下ではほとんど容量の変化がないように見えますが、縦軸を対数スケールに変更すると容量が減り続けているのがわかります。品質設定を落としても容量が減らなかったり、逆に容量が増加することはありません。

この傾向から、jpeg品質設定に関しての方針が導けます。

1. 急激に容量が増加する品質80以上には設定しない。
2. 品質80でも画像のノイズが問題になる場合は、その画像は可逆圧縮のフォーマットを使用すべきである。
3. この設定以下では容量削減効果がなくなる、という品質設定はない。転送量の削減と表示速度の高速化のためには、画像が破綻しない範囲で極力低い画質設定を行うべきである。


#### 画質設定の比較

次に画質比較のパートがあります。

![](https://www.evernote.com/l/AAkNDsgJX4JGnaly36_Gcqp8QxrWNowoCpYB/image.png)

画面上部のプルダウンメニューで画像を選択すると、それぞれのエンコーダー、品質設定で画像とファイルサイズが表示されます。

このパートを使用して品質設定を絞り込んで行く手順を解説します。

まずは任意の画像を一枚ピックアップして、以下の手順で品質を絞り込みます。

* 片方に最高品質の画像を表示し、もう片方に最低品質の画像を表示する。
* 最低品質側の品質を徐々に上げていき、最高品質側と比較して差がわからなくなった段階でストップする。

ツールの標準設定では、品質95と30の画像を並べて、30の方の品質を徐々に上げていきます。こうすることで、平均的な画像での問題のない品質設定が割り出せます。

次に、その設定のまま画像を切り替えていきます。上の画像選択プルダウンはキーボード入力を受け付けますので、フォーカスを当てて↓↓+Enterで画像を切り替えていけます。そうすると、圧縮に弱いタイプの画像が見つかります。

![](https://www.evernote.com/l/AAlZE5VUrOFKv6jwKIWfhBslPzGAhu151QkB/image.png)

淡い色のグラデーションが多用されるような画像はjpeg圧縮に弱く、品質設定を下げるとグラデーションが破綻します。
（縮小表示だとわかりにくいので、上の画像を新しいタブで開いて原寸表示してみてください。）
ここでまた画質設定を少しずつ上げていき、破綻しなくなる品質を割り出します。

この手順を繰り返すと

* 平均的な画像で問題のない品質設定
* 圧縮に弱い画像が破綻しなくなる品質設定
* 圧縮に弱い画像のサンプル内での出現頻度

がわかります。

ここで圧縮に弱い画像の取り扱いを考えます。

* 出現頻度が低く、またビジネス的にも重要ではない画像なら、多少の破綻は許容して平均画像側の品質設定を使用する。
* 出現頻度が高く、重要で破綻が許されないなら、全体のサイズ増加を許容して品質設定を上げる。

という選択肢が考えられます。

#### エンコーダーの比較

画質比較パートでは、エンコーダーの切り替えができます。
このツールでは以下の3つのエンコーダーを比較対象としています。

* [mozjpeg](https://github.com/mozilla/mozjpeg)
* [jpegoptim](https://github.com/tjko/jpegoptim)
* [webp](https://github.com/webmproject/libwebp)

前の作業で、jpegを使用した場合の品質設定を割り出しました。
片側の画像表示をその設定にし、もう片方をwebpの最低品質で表示します。
webp側の品質を徐々に上げていき、jpeg側の画像と遜色ない画質設定を割り出します。

これでjpegとwebpが同程度の画質の場合、どの程度ファイルサイズが削減できるかが割り出せます。
基本的にはwebpの方がファイルサイズは小さくなりますが、サポートするとその分画像の管理工数が増加します。
また、[webpをサポートする環境](https://caniuse.com/#feat=webp)は現状ではモバイル、デスクトップともにChromeだけです。サイトのユーザーのうちどのくらいの割合が恩恵を受けられるかも加味してwebpをサポートするか否かを判断してくだい。


## チェックシート

ここまで設定の確認を行ったら、以下のチェックシートを埋めていってください。
関係者全員が問題意識を共有できる、画質設定の根拠ができます。

* 画質〇〇以上の場合、ファイルサイズが跳ね上がるため、すべての非可逆圧縮画像は画質〇〇以下に設定する。（ 例：80 ）
* 出力画像の特性を鑑み、画像ライブラリは（ jpegOptim | mozjpeg | その他 ）を使用する。
* 平均的な画像が破綻しない画質は〇〇である。（ 例：60 ）
* 圧縮に弱い画像が破綻しない画質は〇〇である。（ 例：75 ）
* したがって、全体の画像圧縮設定は〇〇とする。これにより表示時間が短縮され、コンバージョン率に好影響を与える。
* webPによる転送量削減の効果はjpegと比較して〇〇%程度である。
* webPによる恩恵を受けるユーザーは全体の〇〇%程度と考えられる。
* したがって、webPは採用（ する | しない ）。画像の管理工数の増加と、転送量削減の恩恵が（ 釣り合う | 釣り合わない ）ためである。

## 個人的な感想

最後にレポートツールとサンプル画像の品質設定を詰めていった過程での個人的な感想をまとめておきます。一般的な情報ではありませんのでご参考までに。

* 思った以上に最近のjpegエンコーダーは賢い
* 賢い分エンコード処理は重いが、サイズ削減の恩恵の方が大きいので十分許容範囲
* mozjpegのデフォルト品質設定は75だが、この設定で画像が破綻することはまずない
* 画像の方向性にもよるが品質60ぐらいまでは攻められる
* 品質75から60に変更できればファイル容量はおおよそ3割削減できる

以上、ありがとうございました。