見出し画像

Now in REALITY Tech #6 画像をWebP形式に対応した話

 はじめまして。REALITYのサーバエンジニアの落合と申します。
 今週の「Now in REALITY Tech」はサーバチームからお届けします。

 今回は、最近、REALITYでの画像表示の一部をWebP形式に対応したという話をしようと思います。

WebPとは?

 WebPとはGoogleが開発しているオープンな画像形式です。
 詳細は、Google公式のWebPサイトを見ていただくとして、抜粋すると以下のような特徴があります。

・非可逆と可逆の両方の画像を扱える。
・非可逆モードでは、JPEG/PNGに比べて2〜3割の画像サイズの軽減。
・画像劣化も少ない。

 なかなかいいことづくめです。

WebP形式に対応した効果

 さて、いきなりですが、画像をWebP形式に変更するとどうなるのかをご覧ください。

スクリーンショット 2021-08-05 16.08.20

 俺のアバター、かわいすぎる…
 ではなく、AとBの二つの画像、片方はPNGの元画像、もう一つはWebP変換した画像です。一見して特に違いはありません(この辺りの画像の劣化は写真などではわかりやすいかもしれませんが、REALITYのようなアバター画像ではそれほど顕著には出てこないのかもしれません)。
 が、サイズには大きな違いがあります。なんと約9割減!(1024サイズの画像の場合。アプリで表示する画像は実際にはもう少し小さいサイズにリサイズされています)。

スクリーンショット 2021-08-10 20.30.18

 これはパケットにも優しい。表示速度も速くなる!(はず)

REALITYでの画像の取り扱い

 さて、少しREALITYのサーバサイドの仕組みの話をします。
 REALITYでは画像配信を取り扱うための専用の画像サーバを建てており、Golangでサーバサイドアプリケーションを開発しています。

GolangでのWebP対応状況ですが、標準パッケージ(また、これはx packageという準標準package)ではdecodeパッケージしかありません。
 REALITYの画像はサーバ上ではJPEGかPNGで保存されているので、WebPでレスポンスするなら画像形式をJPEG/PNGからWebPへ変換する必要があるので、今回はgo-libwebpを利用します。
 ただ、現在公開されているWebP変換可能なpackageはどれもpure Golangではなく、libwebpというWebP画像ライブラリの組み込みが必要となります。
 これはGolangのpackageではなくCのライブラリであるため、Golangのサーバアプリケーションが動作する環境自体にinstallする必要があります。
 …ここで一つ問題がありまして、WebP対応前、REALITYの画像サーバはGCPのGAE standardのruntime: go111環境で動作していました。
 このGAE standardというのはマネージド環境で、好き勝手にライブラリなどを入れることはできません。
(ちなみに画像サーバ以外のほとんどのサーバはGKE環境に移行しており、画像サーバだけ諸々の事情で環境移行がされていませんでした)
 そのため、今回はWebP変換対応と合わせて、画像サーバのGKE対応&Docker対応も行い、さらにGolangのversion自体のupgradeも行います。今までGAE standardのgo111環境であったため、go1.11というかなり古いversionを使い続けていたのですが、それともやっとおさらばです。
 結果的には、以下のようなライブラリをdockerfileに追加しています。

FROM alpine:3.14 AS app
RUN apk add --no-cache ca-certificates && \
   apk add --no-cache --update python3 && \
   apk add --no-cache make \
       gcc \
       g++ \
       git \
       libwebp \
       binutils-gold \
       curl \
       gnupg \
       libgcc \
       linux-headers \
       make \
       libwebp-tools \
       libwebp-dev \
       tiff-dev \
       vips-dev \
       libzip \
       libzip-dev

 この辺りの詳細(Golangのバージョンアップ&GAE、GKE環境構築の話)は、また別の機会に詳しくお話しします。

各クライアントでのWebP対応について

 もう一つ気をつけないといけないところは、クライアントでのWebP対応です。
 REALITYはiOSとAndroidのアプリをリリースしています。また一部機能はiOS/Androidアプリに組み込んだUnityを利用しています。
 ですので、iOS native、Android native、UnityのそれぞれがWebP対応しているかを気にしなければなりません。
(webviewを利用している箇所もあるのでブラウザでのWebP対応も気にはなりますが、今回はwebviewについては対象外としています)

 AndroidでのWebP対応はAndroid 4.0以上となっており、現REALITYのバージョン要件はAndroid 7.0以上ですので、全機種で問題なく利用ができます。
 iOSでのWebP対応はiOS 14以上で、現REALITYのバージョン要件はiOS 13以上のため、WebPが扱える機種とそうでない機種両方が存在しています。
 また、Unityについては現状画像を表示する手法も関係して、WebP対応は困難ということがわかりました。

 というわけで、クライアントによって対応もまちまちであるため、サーバではクライアントを判別して画像を出し分ける実装が必要です。
 そのため、現状、REALITYのすべての画像がWebP形式になっているわけではなく、画面によって違いがあります。現状ではアプリ開始時の配信一覧やプロフィール画面などでWebPが使われています。
 対応箇所はどんどん増やしていく予定です。

まとめ

 最近のREALITYの話といいつつ、WebP形式に対応した話がメインになってしまいました。
 パッと見、変わっていないように見える画像もいつの間にかWebP形式になり、少しパケットに優しく、少し表示速度が上がっていたり…REALITYは皆さんの知らない間に日々変化しているのです…ふふふ…そんな風に、皆さんの気付かないうちにREALITYという世界を少しづつ変革していく。そんなサーバエンジニアでありたい…

 こんな風に静かにREALITYを変革していく仲間をREALITYでは募集しております。あ、ユーザーに気付かれなくとも、上司はちゃんと気付いて評価してくれるのでご安心ください。

 それではまた。

おまけ

画像3