https://www.youtube.com/watch?v=GHTO2WKDO6I#t=2h
1 comment | 1 point | by WazanovaNews 約12時間前 edited
FacebookチームのAndroidアプリは、背景にグローバル市場でのAndroid利用者数の急増、それに伴う新興国ユーザの増加(当然そこのユーザをもっとFacebookに囲い込みたいという思惑あり。)という事情を反映して、端末バラエティ / ネットワーク接続環境のフラグメンテーションにしっかり対応して、パフォーマンス改善を重視していこうという方向性にあるようです。
1) 新興市場の理解 by Chris Marra
- FacebookにアクセスするAndroidデバイスは、10,000モデル。
- 世界中の新興国を訪問して市場調査した結果、ローエンド端末 / 中古端末 / プリペイド課金 / 利用時間単位での課金 / モバイルインフラの脆弱さなどの事情を認識。
- Android Year Class: どの時期にどの端末が人気だったかという基準で年度別の主要端末をピックアップし、(過去の人気端末がまだ中古として利用されているだろうから)その区分でクラッシュ率 / 機能別の利用状況を計測して、改善に役立てている。
- 小さい画面サイズも考慮した、画面サイズ別の表示コンテンツの優先度を再検討。
- テクノロジーの浸透度と遅延状況は各国バラバラ
- US: 3G 70.6%、平均遅延 280ms
- インド: 3G 6.9%、平均遅延 500ms
- ブラジル: 3G 38.6%、平均遅延 850+ms
2) ネットワーク環境への対応 by Andrew Rogers
考慮すべきポイント
- 画像ダウンロードは、Android Facebookアプリの85%、Messangerアプリの65%を占めるので改善による期待効果が大きい。
- viewportサイズにあった最適な画像を選択すること。例えば、ユーザにとってはサムネイルだけでよい場合もある。
- ファイルのサイズを小さくしてダウンロード時間を短縮することと、ファイル数が増えるとよけいデータをくう可能性のバランス。
WebPの利用
- Android Facebook / Messangerアプリの画像の90%はWebPフォーマット
- JPEGと比較して7%ダウンロードサイズ削減
- クオリティと圧縮のパラメータを最適化することでJPEG比で30%減
- transparency & animationもサポートするので、PNG比80%削減
- Android OS 4.2以降ではネイティブのWebPデコーダが利用できる。それより古いバージョンでもWebPでダウンロードしているが、libwebp / libpngを使ってJPEG / PNGに戻している。(mozjpeg2.0を利用すると5%節約できる。)
ネットワーククオリティの検知
- 通信テクノロジー(2G/3G/LTE/Wifi)別にどれをとっても、US vs インド/ブラジルでは、2〜3倍のスピードの違いがでる。「このユーザはwifi接続しているから早いはず。」というように、通信テクノロジータイプで単純に判断してはいけない。
- クライアント側で、全てのネットワーク転送(画像ファイル)のスループットを計測
- サーバ側がRound Trip Time(RTT)の見積もりを返して、クライアント側が移動平均値を保持する。
- Poor: 150kbps未満、Moderate: 150-600kbps、Goog: 600-2000kbps、Excellent: 2,000kbps以上というレーティングに分けている。
- レーティングの結果は、機能に動的に反映される仕組みになっている。
- 画像の圧縮率の増減
- ネットワークリクエストをいくつ並列にするかの調整
- ビデオの自動再生のオン/オフ
- コンテンツの事前取得の増減(パフォーマンス改善には効果的なので取得の優先順位も工夫したほうがよい。データ使用量、CPU、バッテリー消費、ストレージスペースなどの数値も合わせて計測しながら判断すること。Facebookアプリでは、起動のはじめの段階で、news feedを取得するネットワークリクエストをしている。)
- Air Traffic Controlという内製ツールを使って、インド/ブラジルなどの国別 & 環境別に、帯域/RTT遅延/パケットロスなどをエミュレートすることができるようになっている。
3) Instagramアプリのパフォーマンス改善 by Tyler Kieft
デザイン
- フラットデザインになると、gradient効果をだすために画像ファイルをディスクから読込んで表示したりせず、しっかした色合いをスクリーンで描くようになるので、メモリ効率がよい。つまりハードウェアの働きを減らせるので、アプリを早くできる、パフォーマンス改善も期待できる。
- 写真/ビデオのキャプチャと編集のフローにおいて、スクリーンをアスペクト比とdpi解像度で、四つに分類し、グループ別にコンテンツレイアウトを最適化。
- Asset Tinting: アセットに対して、プログラムで動的に色をつけている。
- フラットデザインではアセットの形状がシンプルなので色をランタイムで変更できる。
- アセット数が減れば、APKサイズを小さくできる。読込む数が減れば、UIを早く表示できて、メモリの消費を減らせる。早いサイクルで改善を繰り返すことができる。
- Android L向けの機能と宣伝されているが、実はどのAndroidバージョンでも使えるテクニック。
- ColorFilter / Drawable / ImageView も適用し、変更内容をレンダリング。
- immutableなColorFilterオブジェクトの静的キャッシュして、再利用。
- 起動時のアセット数が29から8となり、120 ms (10-20%)の起動時間削減ができた。
- xxhdpi (~480dpi) アセットの追加があれど、全体でもアセット数を半減。
起動時間の改善
- Galaxy S5で0.4秒(<- 0.75秒)、新興国で人気のGalaxy Y(かなり画面の小さい数年前のモデル)でも1.5秒(<- 3秒)で起動できるようになった。
- どう改善するか?
- AndroidのTrace Viewツールでメソッドのトレースをしたり、コードにtiming statementを仕込んだり、とにかく何が遅いのかを調査すること。
- 起動パスから遅いアイテムを外す。遅いコードを書き直す。バックグランドスレッドにdeferする。
- 画像キャッシュ、ビデオキャッシュ、httpクライアント、クッキーストアは、lazy読込みすればよい。
- 対象のオブジェクトを起動時にnullにすることでプログラムを複雑にしたくないので、二段階で処理する。
- UIスレッドで生成したら、バックグランドのスレッドに送る。
- ディスクからSSL証明書の読み出し、キャッシュジャーナルファイルの読込み、クッキーのデシリアライズ/デコードなどの作業をバックグランドで処理。
- 起動時にNewsページが遅くなる問題あり。
- Likeやコメントとしてくれた情報をすぐに提供して更新感をアピールする大事な機能なので、起動時の更新が必須。
- webviewで実装していたが、起動時に多くのスレッドをつくるので、メインのプロセッサーの時間を奪う。かつ、それをコントロールできない。独自にネットワークスタックを立上げ、画像キャッシュも独自に管理するので、アプリ全体から見ると重複作業となる。
- ネイティブ化することで、メインのフィードの後にNewsの読み込みタイミングを遅らせ、ネットワークスタックや画像キャッシュをアプリ全体で共有できるようになった。
4) Q&A
- ユーザの画像投稿では、リトライのロジックを改善したり、クライアント側で圧縮するだけでなく、リサイズもする仕組みに変えている。
ユーザレビューも改善したとのことですが、Facebookは当然全端末のユーザを取り込みたいはずなので、グローバル向けにアプリをだしてると、確かに接続環境/性能の悪い端末のユーザから、「起動/読込みが遅い。」と悪いレビューをもらうことがあるでしょうね。よって、ローエンド端末に配慮したこのような一連の施策は効きますよね。
#facebook #instagram #android