ネットワーク アクセスを最適化する

ワイヤレス通信を使用したデータ転送は、アプリの最もバッテリー消耗の原因の一つとなる可能性があります。ネットワーク アクティビティに関連するバッテリーの消耗を最小限に抑えるには、接続モデルが基盤となる無線ハードウェアにどのように影響するかを理解することが重要です。

このセクションでは、ワイヤレス無線ステートマシンを紹介し、アプリの接続モデルがワイヤレス通信ステートマシンとどのようにやり取りするかについて説明します。そこで、いくつかの手法を紹介します。この手法に従うことで、アプリのデータ消費によるバッテリーへの影響を最小限に抑えることができます。

無線通信のステートマシン

ユーザーのデバイスのワイヤレス無線通信には、バッテリーの消費量を最小限に抑える省電力機能が組み込まれています。完全にアクティブなとき、ワイヤレス無線は大量の電力を消費しますが、非アクティブまたはスタンバイ状態では、無線の消費電力はほとんどありません。

覚えておくべき重要な要素の 1 つは、無線が即座にスタンバイ状態から完全なアクティブ状態に移行できないことです。無線通信の「パワーアップ」に関連するレイテンシ期間があります。そのため、未使用時に電力を節約するために、無線通信の「パワーアップ」に関連するレイテンシを最小限に抑えるために、バッテリーは高エネルギー状態から低エネルギー状態にゆっくりと移行します。

一般的な 3G ネットワークの無線通信のステートマシンは、以下の 3 つのエネルギー状態で構成されます。

  • 最大電力: 接続がアクティブなときに使用され、デバイスが可能な限り最高のレートでデータを転送できるようにします。
  • 低電力: バッテリーの消費電力を約 50% 削減する中間状態です。
  • スタンバイ: ネットワーク接続がアクティブでないときの最小限の電力消費状態。

低状態とスタンバイ状態では、バッテリーの消耗が大幅に少なくなりますが、ネットワーク リクエストのレイテンシが大幅に短縮されます。低状態からフルパワーの状態に戻るまでには約 1.5 秒かかり、スタンバイ状態からフルパワーの状態に戻るまでに 2 秒以上かかることがあります。

レイテンシを最小限に抑えるため、ステートマシンは遅延を使用して低エネルギー状態への遷移を延期します。図 1 では、AT&T が測定した一般的な 3G 無線通信のタイミングを使用しています。


図 1. 一般的な 3G 無線通信ステートマシン

各デバイスの無線ステートマシン、特に関連する移行遅延(「テールタイム」)と起動レイテンシは、使用する無線技術(3G、LTE、5G など)によって異なり、デバイスが動作している携帯通信会社のネットワークによって定義および構成されます。

このページでは、AT&T のデータに基づいて一般的な 3G ワイヤレス無線の代表的なステートマシンについて説明します。ただし、一般原則とその結果として得られたベスト プラクティスは、すべてのワイヤレス無線実装に適用されます。

この方法は、ユーザーがウェブ ブラウジングする際の望ましくないレイテンシを防ぐことができるため、一般的なモバイルウェブ ブラウジングに特に効果的です。また、テールタイムが比較的短いため、ブラウジング セッションが終了すると、無線通信は低エネルギー状態に移行できます。

残念ながら、このアプローチは Android のような最新のスマートフォン オペレーティング システムでは非効率なアプリにつながる可能性があります。Android では、アプリはフォアグラウンド(レイテンシが重要)とバックグラウンド(バッテリー駆動時間が優先される)の両方で実行されます。

アプリが無線ステートマシンに与える影響

新しいネットワーク接続を作成するたびに、無線通信は完全な電力状態に移行します。前述の一般的な 3G 無線ステートマシンの場合、転送時間(さらに 5 秒のテールタイム)が続く間はフルパワーの状態が維持され、その後 12 秒間低エネルギー状態で維持されます。そのため、一般的な 3G デバイスでは、すべてのデータ転送セッションで無線通信が少なくとも 18 秒間電力を消費します。

実際には、1 分間に 3 回、1 秒のデータ転送を行うアプリは、ワイヤレス通信を永続的にアクティブに保ち、スタンバイ モードに入ると同時に高電力の状態に戻ります。


図 2. 1 分ごとに 3 回実行される 1 秒間の転送でのワイヤレス無線通信の電力使用量。図は実行間の「パワーアップ」レイテンシを除外しています。

これに対して、同じアプリがデータ転送をバンドルし、毎分 3 秒の転送を 1 回実行すると、無線通信は合計で毎分 20 秒だけ高電力状態を維持します。これにより、無線通信は毎分 40 秒間スタンバイ状態になり、バッテリー消費量を大幅に削減できます。


図 3. 1 分ごとに 1 回実行される 3 秒間の転送でのワイヤレス無線通信の電力使用量。

最適化手法

ネットワーク アクセスがバッテリー駆動時間に与える影響を理解したところで、次に、高速で滑らかなユーザー エクスペリエンスを提供しながら、バッテリーの消耗を抑えるためにできることをいくつか見ていきましょう。

一括データ転送

前のセクションで説明したように、データ転送をバンドルして、より多くのデータをより少ない頻度で転送することは、バッテリー効率を向上させる最善の方法の一つです。

もちろん、ユーザーの操作に対してアプリが直ちにデータを送受信する必要がある場合は常に可能ではありません。これは、データを予測してプリフェッチすることで軽減できます。サーバーへのログや分析の送信や、緊急性のない、アプリから開始されるその他のデータ転送などの他のシナリオは、バッチ処理とバンドルに非常に適しています。バックグラウンド ネットワーク転送のスケジュール設定のヒントについては、アプリ開始タスクの最適化をご覧ください。

データをプリフェッチする

データのプリフェッチも、アプリが実行する独立したデータ転送セッションの数を減らす効果的な方法です。プリフェッチを使用すると、ユーザーがアプリ内でアクションを行うと、アプリは次の一連のユーザー アクションに必要である可能性が最も高いデータを予測し、そのデータを 1 つの接続で最大容量で一気に取得します。

転送をフロントローディングすることで、データのダウンロードに必要な無線通信の有効化の数を減らすことができます。その結果、バッテリーを節約できるだけでなく、レイテンシの改善、必要な帯域幅の低減、ダウンロード時間の短縮も実現できます。

また、プリフェッチは、ダウンロードが完了するのを待ってからアクションの実行やデータの表示に起因するアプリ内レイテンシを最小限に抑えることで、ユーザー エクスペリエンスを改善します。

以下に実用的な例を示します。

ニュース リーダー

多くのニュースアプリは、カテゴリが選択された後にのみ見出しをダウンロードし、ユーザーが記事を読みたいときにのみ記事全文をダウンロードし、スクロールして表示されるときと同じようにサムネイルをダウンロードすることで帯域幅の削減を試みます。

このアプローチを使用すると、ユーザーが見出しのスクロール、カテゴリの変更、記事の閲覧を行うユーザーの大部分のニュース閲覧セッションの間、ラジオはアクティブのままになります。さらに、エネルギー状態が常に切り替わるため、カテゴリの切り替え時や記事の読み取り時に大幅なレイテンシが発生します。

より適切なアプローチは、起動時に妥当な量のデータをプリフェッチすることです。最初のニュースの見出しとサムネイルのセットから始まり、低レイテンシの起動時間を確保し、残りの見出しとサムネイル、少なくとも主要な見出しリストから入手できる各記事の記事テキストを継続します。

もう 1 つの方法は、すべての見出し、サムネイル、記事テキスト、そして場合によっては記事全体の画像をプリフェッチすることです。通常は、事前に決められたスケジュールでバックグラウンドでプリフェッチします。この方法では、使用されていないコンテンツをダウンロードする際に大量の帯域幅とバッテリー駆動時間を消費するリスクがあるため、慎重に実装する必要があります。

その他の考慮事項

データのプリフェッチには多くのメリットがありますが、過剰にプリフェッチを使用すると、使用されていないデータをダウンロードすることで、バッテリーの消耗と帯域幅の使用量(およびダウンロード割り当て)が増加するリスクも生じます。また、プリフェッチの完了をアプリが待機している間、プリフェッチによってアプリの起動が遅延しないようにすることも重要です。具体的には、データを段階的に処理することや、アプリの起動に必要なデータが最初にダウンロードされて処理されるように優先して連続転送を開始することを指します。

データをどの程度積極的にプリフェッチするかは、ダウンロードするデータのサイズと、データが使用される可能性によって異なります。大まかな目安として、前述のステートマシンに基づくと、現在のユーザー セッション内で使用される可能性が 50% のデータの場合、通常は約 6 秒間(約 1 ~ 2 メガバイト)プリフェッチできます。これを超えると、未使用のデータのダウンロードにかかる費用と、そもそもそのデータをダウンロードしないことによる削減の可能性が同等になります。

一般的には、2 ~ 5 分ごとに 1 ~ 5 MB の規模で新たなダウンロードを開始すれば済むように、データをプリフェッチすることをおすすめします。

この原則に従うと、動画ファイルなどの大規模なダウンロードは一定間隔(2 ~ 5 分ごと)でチャンクでダウンロードされ、数分以内に表示される可能性が高い動画データのみが効率的にプリフェッチされる必要があります。

解決策の 1 つは、Wi-Fi に接続している場合にのみ(可能であればデバイスの充電時にのみ)完全なダウンロードが行われるようにスケジュールすることです。WorkManager API はまさにこのようなユースケースをサポートしており、デバイスが充電や Wi-Fi への接続など、デベロッパーが指定した基準を満たすまでバックグラウンド処理を制限できます。

リクエストを行う前に接続を確認する

セル信号の検索は、モバイル デバイスで最も電力を消耗する操作の一つです。ユーザーが開始するリクエストのベスト プラクティスは、接続ステータスと接続測定をモニタリングするに示すように、最初に ConnectivityManager を使用して接続を確認することです。ネットワークがない場合、アプリはモバイル無線通信の検索を強制しないため、バッテリーを節約できます。これにより、接続が確立されたときにリクエストをスケジュール設定し、他のリクエストと一括して実行できます。

プールの接続

バッチ処理とプリフェッチのほかにも、アプリのネットワーク接続をプールするという方法もあります。

一般的に、新しいネットワーク接続を開始するよりも、既存のネットワーク接続を再利用する方が効率的です。また、接続を再利用すると、輻輳や関連するネットワーク データの問題に、ネットワークがよりインテリジェントに対応できるようになります。

HttpURLConnection とほとんどの HTTP クライアント(OkHttp など)では、デフォルトで接続プーリングが有効になっており、複数のリクエストで同じ接続を再利用します。

まとめと今後の展望

このセクションでは、ワイヤレス通信について多くのことを学びました。また、バッテリーの消耗を抑えながら高速で応答性の高いユーザー エクスペリエンスを提供するために幅広く適用できるいくつかの戦略についても学習しました。

次のセクションでは、ほとんどのアプリに共通する 3 種類のネットワーク操作について詳しく説明します。各タイプのドライバと、これらのインタラクションを効率的に管理するための最新の手法と API について学習します。