フロントエンドの画像軽量化まとめ【2017年版】

こんにちは、面白法人カヤック フロントエンドエンジニアのごんです! 今回は、Webの画像の軽量化について、フロントエンドチームで使ってるツールややり方をまとめてみました。 画像の軽量化などで困ってる方の参考になればと思います。

なぜ画像の軽量化をするのか

Webサイトのローディング時間は、ユーザーの直帰率やコンバージョン率に関わる大切な指標です。 ローディング時間に関わる要因はさまざまですが、 特に画像は容量が大きいため、画像の軽量化をすることで表示速度の大きな改善を望むことが出来ます。 例えば、当ブログのある記事は、画像が全体の容量の約1/3を占めていました。

f:id:umai_bow:20170927154506p:plain

一般に、PhotoshopやIllustratorから出力された画像は、十分な色数やクオリティで出力されており、 ツールなどを使うことで、見た目をそれほど損なわず、容量を大幅に減らすことができます。

f:id:umai_bow:20170927154524p:plain

また、一部の画像形式には、メタデータと呼ばれる撮影機器や編集ソフトの情報など、表示には不要な情報が含まれることがあり、それらの情報を削る目的もあります。

f:id:umai_bow:20170927154456p:plain

PNG

PNGの特徴

PNGは、ざっくり言うと画素列をgzipした形式です。 色数を限定したインデックスカラーモードと、全ての色が使えるトゥルーカラーモードがあります。 一般的には、インデックスカラーモードのほうが容量が少なく、またgzipをかけるため、規則的な画像のほうが容量が小さくなる傾向があります。

f:id:umai_bow:20170927154519p:plain

後者の特徴は意外と馬鹿にできず、 パターンのある画像でも、わずかにノイズを加えると容量が大きくなってしまうという傾向を持っています。 例えば、先ほどの虹色の画像に知覚できない程度のノイズを加えた場合、10倍以上の容量増大となります。

f:id:umai_bow:20170927154521p:plain

なので、PNGの容量を少なくする戦略は大きく以下の2つになります。

  • 色数を減らす
  • 画素の起伏を減らす(規則的にする)

次の節でツールの紹介をしますが、これらの特徴を踏まえて、画像を書き出す段階で、容量が大きくならないように工夫することも重要です。

PNGの軽量化ツール

pngquant

代表的なPNGの軽量化ツールです。 色数を減らしたり、ポスタライズすることでPNGの軽量化ができます。 CUIツールなので、ターミナルから操作することが基本になりますが、いっぺんに軽量化をかけたり、ビルドタスクに組み込むときに便利です。 引数で0-100のクオリティや色数が指定できます。

pngnq

pngquantと似た機能ですが、ニューラルネットワークを使った最適化が行われるらしいです。

ImageAlpha

pngquantやpngnqをGUIで確認しながら適用できるツールです。 元画像と比較しながら軽量化をできるので、クリティカルな画像を圧縮するときや、クオリティにギリギリまで拘りたいときに便利です。 逆に、大量の画像を一気に処理する場合にはあまり向かないかもしれません。

JPEG

JPEGの特徴

JPEGがざっくりいうと、画像を細かく分割したあと、周波数空間に直して高周波成分(特に色相)を取り除いた形式です。 わかりませんね。 JPEGは実写やノイズの多い画像が向いている形式です。 PNGとは違い、劣化圧縮が基本でPhotoshopなどから保存するときにクオリティを0〜100の数値で選ぶことになります。 クオリティを下げすぎると、ブロックノイズと呼ばれる矩形のノイズや、モスキートノイズと呼ばれる波打つようなノイズが生じます。 以下の画像では、圧縮率を上げすぎてしまったため、船のマストの辺りにモスキートノイズが強く発生しています。

f:id:umai_bow:20170927154515j:plain

JPEGはPNGと異なり複雑な形式のため、人類が工夫してどうこうできることは少ないです。 目視で確認しながら、適切にクオリティを設定するのがベストですが、いくつか軽量化に便利なツールがあるため紹介をします。

JPEGの軽量化ツール

jpegtran

jpegtranはJPEGの最適化をおこなって、無劣化で容量の削減をすることが出来ます。 その他にも画像の反転や回転も出来ます。 多くのjpegエンコーダで利用されている、由緒正しいツールです。

mozjpeg

mozjpegはMozillaが公開しているjpegエンコーダです。 libjpeg-turboを基にしており、一般的なエンコーダより小さいサイズでエンコードができるとされています。 また、PNG画像にもmozjpegを利用することで、サイズの縮小や画質の向上が望めるとされています。

guetzli

guetzliはGoogleが公開しているjpegエンコーダです。 2017年に発表されたライブラリで、まだ新しく、情報や評価はまだ定まっていないように見えますが、Butteraugliと呼ばれる独自の評価関数を採用しており、一般的なエンコーダより20〜30%程度小さいサイズでエンコードができるとされています。 エンコードにはそれなりに実行時間がかかるようです。 lossyな圧縮だけでなく、qualityを100にすることで、無劣化の圧縮もできます。

SVG

SVGの特徴

SVGは、ざっくり言うとベクター画像のパスデータをHTMLのようなタグで表現した形式です。 実際には、パスデータだけではなく、ぼかしなどのフィルターやラスタ画像、アニメーションなども含むことが出来ます。 SVGは、PNGやJPEGなどとは異なり、バイナリではなくテキストのデータで、ベクター画像のため、拡大してもボケたりジャギったりしません。 また、CSSで色を変更できたり、JSで操作できるなど、他の画像形式にはない特徴を持っています。

f:id:umai_bow:20170927154527p:plain

SVGは一般的には容量が少ない傾向にありますが、専用のツールを使うことで、無駄なデータを除去し、軽量化をすることが出来ます。 また、テキストデータのため、サーバでgzip圧縮をかけて配信すると容量が大きく減るという特性があります(逆にPNGやJPEGは減りません)。 SVGを多用するサイトでは、サーバのgzip圧縮を有効にするようにしましょう。

SVGの軽量化ツール

SVGO

SVGOをNodeベースのSVG最適化ツールです。 不要なIDやクラス名を除去や、パスデータの最適化やマージなど、かなり色々なことをやってくれます。 SVGOによる最適化は非劣化圧縮ですが、メタデータなどが抜け落ちることで、セマンティックな情報が抜け落ちることがあるかもしれません。

まとめ

今回は個別の画像形式について、軽量化の方法をまとめてみました。 画像自体の軽量化だけではなく、転送量の削減に目を向ければ、サーバサイドで出来る対策や、スプライト化・遅延ロードなど、様々な方法が考えられます。 適材適所で利用し、軽いサイトを作りましょう〜。

おしらせ

カヤックでは、画像容量の1byteまで拘りたいフロントエンドエンジニアを募集しています。 応募は下記からどうぞ!

【新卒採用】 https://www.kayac.com/recruit/fresh

【中途採用】 https://www.kayac.com/recruit/career

【インターン】 https://www.kayac.com/recruit/intern