WebPでモバイルアプリの通信量を劇的に削減する

モバイルファースト室の @slightair です。 クックパッドの iOS/Android アプリは、少し前のバージョンからWebP形式の画像をサーバから取得して表示するようにしています。 この記事では、なぜ画像形式をWebPに切り替えたのか、また切り替える上で注意した点などを説明します。

Cookpad アプリと画像

クックパッドのアプリはユーザさんに投稿していただいたレシピを表示するアプリケーションです。その性質上、レシピ画像や調理手順、検索画面のサムネイルなどたくさんの画像をサーバから取得して表示する必要があります。

画像の数が増えたりサイズが大きくなればなるほど通信量が増えます。最近はスマートフォンの画面サイズがどんどん大きくなっているので、それに合わせて取得する画像を大きくしていくとさらにファイルサイズが増え、通信量も増えていってしまいます。

サーバとやりとりするデータが多くなると、画像が表示されるまでユーザは待たされることになってしまいます。 少しでもデータを小さくしたい…。

WebP

WebP とは Google が開発している画像形式のひとつです。 https://developers.google.com/speed/webp/

WebPはウェブサイトの通信量軽減と表示速度の短縮のために開発されました。 JPEGやGIF、PNGを置き換えることができます。 可逆圧縮モード、非可逆圧縮モード、アルファチャンネルなどをサポートしています。 可逆圧縮モードのWebPはPNGと比べて26%小さくなり、非可逆圧縮モードではJPEGと比べて25-34%小さくなるとしています。

クックパッドのアプリで表示しているレシピ画像などは、写真であるためJPEG形式の画像を表示していました。

f:id:Slightair:20141201192839p:plain

この画面を大きく占める、今日のおすすめのレシピの画像をWebP形式に変換してファイルサイズを比べてみましょう。

この画像です。

f:id:Slightair:20141201192916j:plain

レシピはこちらです。

以下の様なコマンドを用いて変換しました。cwebp はGoogleが提供している変換ツールです。

cwebp -q 90 717981.jpg -o 717981_90.webp

以下のような結果になりました。

file name file size(Bytes)
717981.jpg 90,602 100.00%
717981_50.webp 18,344 20.25%
717981_60.webp 20,882 23.05%
717981_70.webp 23,550 25.99%
717981_80.webp 30,214 33.35%
717981_90.webp 51,288 56.61%

指定するqualityの値にもよりますが、かなりファイルサイズが削減できていますね。 見た目が変わらずこれだけファイルサイズが削減できるのであればとても期待できますね。

WebP形式の欠点には対応アプリケーションが少なく、JPEGやPNG形式と比べて扱いにくいというものがあります。 Facebookではこのような事例があったみたいです。

グーグルの画像形式「WebP」を試行するFacebook--ユーザーからは不満の声も - http://japan.cnet.com/news/commentary/35031278/

しかし、モバイルアプリケーションの場合はPCブラウザと違い表示するだけなので、ユーザさんがブラウザの右クリックメニューからWebPの画像を保存するようなことはできないはずです。 保存したレシピ画像が見られない開けないといったトラブルもなさそうなので、気軽に採用できそうです。

WebP形式の画像をアプリで表示する

WebP形式の画像を表示するにはどうしたらよいのでしょう?

Android の場合は、4.0 以上であれば標準で対応しているとのことです。 http://developer.android.com/guide/appendix/media-formats.html

しかし、クックパッドアプリでは 4.2 や 4.3 の環境で画像の表示が崩れるなどの問題が起きたため、4.4 以上の端末のみを対象にWebPサポートを有効にしています。

iOS の場合は、libwebp を組み込む必要があります。 クックパッドアプリの場合は画像の読み込み・表示に SDWebImage というライブラリを使っていました。このライブラリではオプションでWebPサポートを有効にすることができるので、これを導入することで既存のコードをほとんど変えることなくWebPを表示することができるようになりました。

注意した点

WebPを採用する上で、画質が本当に落ちないか、WebPにしたことで一部の画像が表示されないなどの問題が起きないかを特に気をつけていました。

料理の画像を表示するアプリケーションなので、画質が劣化することで料理がおいしくなさそうになってしまうととても残念です。そこでWebPとJPEGの画像を並べて表示し、極端な劣化が起きていないか検証するアプリケーションを作りました。社内でレシピ画像の見た目に変化がないか検証してからWebPを導入しています。

またWebPにしたことで低スペックな端末でレンダリングに時間がかかるようになってないかなども検証しました。通信量が減ってダウンロード時間が減ったとしてもそれの表示処理に時間がかかってしまっては意味がありません。ただ、これについては問題になりませんでした。

社内で検証して、これはいけそうだという話になっても、すぐにすべてを置き換えるようなことはしませんでした。検証したものの予期せぬ影響が見つかってしまった、そういう場合でもモバイルアプリはすぐに更新ができません。 そこで、WebP形式の画像配信を一部のユーザに対して行い、少しずつ対象をふやすような工夫をしていきました。幸い問題がおきなかったので、Androidはバージョン 4.3.1 から、iOSはバージョン 6.4.0 からすべてのユーザーを対象にするようになっています。

おわりに

サーバから取得した画像を多く表示するようなアプリの場合、画像のダウンロードにかかる通信量は無視できません。 WebPは画質をほとんど落とすことなくファイルサイズを減らすことができるので、ダウンロード待ち時間を減らしてユーザ体験を向上させる効果が期待できます。 サービス提供側にも通信量が減らせるメリットがあります。

少しずつでも重ねていけばこのような改善はアプリの性能向上に効いてくると思うので、色々試していきたいですね。

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/