ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Appにおけるネットワーク遅延の低減
CPUのパフォーマンスとネットワークの伝送速度は向上し続けていますが、光の速度はこれ以上上がらない限界の一つです。ネットワークのラウンドトリップ時間を短くし、ネットワーク操作時のラウンドトリップ回数を最小限にすることで、Appの応答性と効率性を最大限に高めるAPIとベストプラクティス紹介します。
リソース
関連ビデオ
WWDC22
WWDC21
WWDC19
WWDC18
WWDC15
-
ダウンロード
♪ (Appにおける ネットワーク遅延の低減) "Appのにおける ネットワーク遅延の低減" へようこそ Stuart Cheshireです ネットワークAppの動作が 遅くなる要因について お話しします 次に同僚のVidhi Goelに移り ネットワークAppの応答性を 高めるために使える テクニックとAPIについて 説明します まずiOSのWWDCベータ版で すでに見たであろうことに ついて説明しましょう 設定を見ると セクションに "応答性"という 新しい項目があります アップロードのスループットや ダウンロードのスループットおよび アイドル時のping時間は すべて興味深いものですが ネットワークAppの応答性に 影響する主な要因は アイドル状態ではなく稼働状態での ネットワークの応答性です 一般的なインターネット速度試験の アイドルping時間の測定値は インターネット接続を使って いないときの動作を示します 重要なのはインターネット 接続使用時の インターネット接続状態です をタップします ネットワークトラフィックが 生成され 数秒間のネットワーク測定後 ネットワークの動作が 正常かどうかが 通知されます このツールはミリ秒 単位ではなく1分あたりの ラウンドトリップ数(RPM)で ネットワークの応答性を報告します この新しいRPM測定基準は 多くの人にとってミリ秒が 抽象的すぎるために 作成されました 値が高ければより優れている 指標についても 皆が理解しています RPM測定基準は 数百RPMから 数千RPMまでの範囲の 数値を生成します これは車のエンジンの RPMのようなものです macOSには"NetworkQuality"と 呼ばれる コマンドライン バージョンもあります 自宅や職場のネットワークでは pingの時間が 長いと考えられますが それはアイドル状態です このネットワーク品質テストは iPhoneまたはMac上で あなたが実行します またネットワーク使用中に 応答性が大幅に 低下することがあります さらに悪いことに ネットワークには20ミリ秒の アイドルラウンドトリップ時間が あるかもしれません かなり素晴らしく聞こえるでしょう しかし作業条件下では ラウンドトリップ時間が 最大600ミリ秒以上に なることがあります それは30倍悪いです 作業環境における ネットワークの応答性は Appのユーザー体験 にとって重要です この問題は常に発生しています ビデオ会議中に音声や ビデオがフリーズしたり ドロップアウトしたり する場合は特にそうです ネットワーク遅延が大きければ 全Appに悪影響を及ぼしますが 私たちは慣れてきたため ビデオ会議に影響する場合の 多さに注目しています ビデオ会議で問題が 発生した場合は インターネット接続を アップグレードして 解決すると思います 数メガビット/秒から ギガビット以上に なってもまだ問題は起こります ビデオ会議では数メガビット/秒が 十分である必要がありますが これらの問題が解決しないのは なぜでしょうか ネットワーク内のバッファが 過度に大きい場合 バッファがいっぱいになると スループットは向上せず 遅延が発生します 通常インターネットは このように動作しており パケットはネットワークを介して 高速で流れると考えています しかしクラウド内を見ると 実際にはこのように 機能することがわかります ネットワークから 出てくるパケットは 入ってきたパケットとは異なります パケットはネットワーク内の 過度に大きいバッファに 長時間置かれます このようにバッファが 大きすぎる現象は "バッファブロート"と呼ばれ ネットワークの日常的な利用に 影響を与えているにもかかわらず これまで大々的に測定されることは ありませんでした 良いニュースは 制御された遅延キューイング アルゴリズムである Codelなどバッファ ブロートを排除する 最新のキュー管理 アルゴリズムがあることです ネットワークが キューを短くし続けると パケットがネットワークで 待機する時間が 大幅に短縮されます 高いスループットと低い遅延を 同時に実現できます 二者択一やゼロサムではありません 私たちは業界と協力して よりスマートなキュー管理 アルゴリズムを導入し 稼働状況下でのネットワークの 応答性を向上させています しかし今のところ優れた ユーザー体験を提供したい場合は 現在のようにAppを インターネットに対応させたいと 考えるでしょう バッファブロートはAppで 発生するネットワーク遅延の 大きな要素ですが 遅延の原因は それだけではありません ソフトウェアとハードウェアの 処理時間があります CPUの処理速度が向上すると この処理時間は短縮され続けます 実際のデータ転送時間があります データレートが キロビットからメガビット ギガビット/秒に増えると 伝送時間は短縮され続けます ネットワークでのバッファリング による遅延が発生します 前述のように私たちは 業界と協力して これらの遅延の短縮に 取り組んでいます しかし信号の伝播遅延は 常にあります 1990年代には米国を横断す スタンフォード大学から MITへのping時間往復つまり 海岸から海岸への往復は すでに100ミリ秒未満でした これはすでに光速の限界に近いため それほど向上することはありません 私たちは他3つの遅延短縮に 取り組んでいますが 光の遅延がなくなることは ありません そのためネットワークの 往復時間を考慮した App設計が重要なのです ネットワークの往復時間を 考慮に入れるとどのような種類の Appが話題になりますか ネットワーク遅延が高ければ ビデオ会議に 深刻な影響が出ることは 誰もが知っています 高いネットワーク遅延で オンラインゲームに深刻な影響が 出ると誰もが知っています ただしこれはネットワークを使う すべてのAppに影響します 天気予報や株価情報それから 道案内などを入手すること についてお話しています これはウェブ閲覧に影響します これはストリーミングビデオ 視聴中の早送りに影響します Appのネットワーク待機中に アニメーション化された スピン遅延インジケータが 何個のAppに入っているか 考えてみてください あなたのAppに 入っているでしょう Appがハングしたと ユーザーが思わないように "お待ちください"の表示が出ます 低速ネットワーク待機中に ユーザに見せるものに 多大な努力を払うのは 素晴らしいことですが 待ち時間を短くするためにも 同様の努力を払う必要があります ネットワークからの データ待機中に 遅延インジケータを表示する Appがある場合は これらの待機時間の短縮に 使えるテクニックがあります Appがネットワーク データを待機する 時間は 1回のネットワーク往復に かかる時間と Appが必要とするネットワーク 往復数の計算式です App開発者は 基礎となるネットワークの 往復時間を改善するために多くの ことを行うことはできませんが Appに必要な往復回数を 制御できます 私の同僚であるVidhi Goelが その方法を説明します ありがとう Stuart Vidhiです 今日はAppのネットワーク 遅延短縮のために 開発者としてできることについて お話したいと思います Appの応答性は ネットワーク往復数に 反比例します 最新のネットワークプロトコルを 採用することで ネットワークの往復数を削減し Appを非常に軽くする 方法をご紹介します Appを高速化するには HTTP/3やQUIC TCP Fast Open TLS1.3やMultipath CPなどの 最新ネットワークプロトコルを 採用します このような手法により Appはユーザーへの データ配信の際に複数回の 往復を削減できる可能性があります これらの最新のプロトコルすべてに サーバ側のサポートが必要なため プロバイダの準備状況を ご確認ください これらのテクノロジーは すべてiOSとmacOSで 利用できます ではこれらのテクノロジーについて 見ていきましょう まずiOS 15と macOS Montereyでは デフォルトでHTTP/3とQUICが 有効になっています QUICはTCPやTLSよりも はるかに高速な接続を 設定できるトランスポート プロトコルです ヘッドオブライン ブロッキングを削減することで QUICはユーザーへの データ配信遅延を 大幅に削減できます 最高なのはここです URLSessionをすでに使用している場合は すべて設定済です ネットワーク フレームワークAPIを使って 独自のAppレイヤを提供して QUICを活用したい場合は QUICパラメーターで NWConnectionを作成し TLS Application-Layerプロトコルまたは ALPNを設定します Appでのこれらの テクノロジーの使用方法は "HTTP/3とQUICによる ネットワーキングの加速" セッションをご覧ください QUICは多くの シナリオで役立ちます ただし一部のAppでは TCPが適切な選択肢である 場合があります TCPを使用する場合TCPハンド シェイクとともにAppデータを 送信することでラウンドトリップ 全体を排除できます TCP Fast Openは ネットワークフレームワークおよび ソケットでサポートされています NWConnectionsで使うには 2つの選択肢があります 1つ目のオプションは接続で Fast Openを許可することです この場合Appはハンドシェイクで 送信される初期データを提供します これを有効にするには allowFastOpenパラメータを trueに設定し接続を作成します 次にstartを呼び出す前に sendを初期データで 呼び出します TCP Fast Openを使う場合は ハンドシェイクを使って 冪等な要求のみを送信するよう 注意する必要があります 冪等とは基本的に データをネットワーク経由で 安全にリプレイできることを 意味します TCP Fast Openを使う もう1つの方法がありますが Appが独自の初期データを 送信する必要はありません AppがTCPを介した TLSを使っている場合は 初期データとして TLSハンドシェイクメッセージの 送信を選択できます これを有効にするには TCP固有のオプションに移動し enableFastOpenを trueに設定します TCPFastOpen を使用するには Networkフレームワーク APIの使用をおすすめしますが Appがソケット上に 構築されている場合は それぞれのフラグを指定して connectx APIを呼び出して ハンドシェイクで冪等なデータを 送信するように指定します 私は何度か冪等について 述べました その意味するところや ハンドシェイクを使って 冪等な要求のみを送信することが 重要な理由について説明します 一度以上実行した場合 冪等とリプレイセーフな操作は 追加の影響を与えない操作です たとえばユーザが developer.apple.comの ウェブページにアクセスすると このウェブページの HTTP GETリクエストが TCPハンドシェイクで 送信されます この要求の確認応答が 遅延したかネットワーク内で ドロップされた場合 デバイスはHTTP GET リクエストを再送信します これは別のサーバにルーティング される可能性があります 今回は HTTP応答とともに 確認が到着します HTTP GET要求は ネットワークを介して 再送信された場合には 追加の影響を与えないため 冪等リクエストと見なされます さてユーザーが 新しいiPhone 12を 購入しようとしているとします この操作のために 送信されたHTTPリクエストは 冪等なリクエストではありません データがネットワーク経由で リプレイされるたびに リクエストが異なるサーバに 送られると 複数のトランザクションが 発生する可能性があります これを念頭に置いて TLS1.3について説明します TLS1.3ではTLS1.2と 比較するとハンドシェイクから ラウンドトリップ全体が 削除されます またセキュリティが強化されます URLSessionとNWConnectionの iOS13.4では デフォルトで有効になっています TLS1.3プロトコルは早期データ サポートを定義しています これは冪等なリクエストと TLSハンドシェイクメッセージを 送信することで さらに別のラウンド トリップを節約できます ではギアを切り替えて ネットワーク遅延短縮において 少し異なる動作をする Multipath TCPを見てみましょう Multipath TCPにより シングルTCP接続が デバイス切り替えとして 継続できるようになります Multipath TCPの 低遅延機能を取得するには インタラクティブモード APIを使います 新しい接続の確立に必要な すべてのラウンド トリップが節約され データパケットの 高速ネットワークパスが 自動で選択されます クライアントから オプトインするには URLSession構成または NWParametersで multipathServiceType プロパティを interactiveに 設定します これらの最新テクノロジーで 節約できるラウンド トリップ数を把握するには 基準点から始めましょう Appが現在TCP上でTLS1.2を 実行しているとします この場合ユーザーに最初のバイトを 取得するには4回の ラウンドトリップが必要です サーバーがTLS1.2から TLS1.3に切り替わると 接続がラウンドトリップ 全体を削除します 接続でTCP Fast Openを 有効にすると さらに別のラウンド トリップが節約されます iOS 15ではQUICを介した HTTP/3により ラウンドトリップが 2回に削減されます QUICプロトコルは早期データ サポートも定義しているため 1回のラウンドトリップを さらに削減できます Appleでの測定結果に基づき ユーザーは600ミリ秒に 達することもあるような ラウンドトリップ回数をよく見ます Appにとっての意味を 見てみましょう 600ミリ秒で4回の ラウンドトリップを行うと ユーザーはデータ到着まで約2秒半 待機しています これはネットワークのスピナーを 待機して見るための膨大な時間です 最新のネットワークプロトコルを 採用することで 最初のバイトまでの時間を 2.4秒から 約0.5秒に短縮できます ユーザーはデータが 1秒半前に到着すると その違いがはっきりとわかります 高いネットワークパフォーマンスを 求めているすべての開発者は ラウンドトリップの回数に 注意する必要があります これが大きな勝利です ここまでお話した すべてのテクノロジーは 実際のネットワーク環境での Appのネットワーク遅延の 短縮に役立ちます 5G LTEまたは高速Wi-Fi ネットワークでAppを試験すると Appの応答性が問題なく 感じられることがあります しかしユーザーが最適な ネットワーク環境で Appを使っているとは限りません 実際のネットワークを シミュレートするため iOS用の Network Link Conditionerツールが デベロッパ設定メニューから 利用できます macOSの場合は Apple Developer Webサイトから ダウンロードできます このツールはユーザーが 日常的に経験する可能性のある さまざまなネットワーク条件での Appのテストに 信頼性が高く繰り返し利用できます 先程 Stuartがネットワークの ラウンドトリップ時間の短縮は できないと言っていたと思います それは違います Appのトラフィックを システムに正しく通知することで ネットワークの往復時間を 短縮する方法を 説明します ほとんどのAppでは送受信する トラフィックが混在しています 多数のAppを実行するときに ユーザーのデバイスから やり取りされるデータが 大量にあります 自宅やオフィスWi-Fiなど 実際のネットワークでは 多数のデバイスが同一の ネットワークを共有しています これらのデバイスは 一連のAppを使いながら 大量のデータを同時に送受信します この共有ネットワークで長い キューを作成しないようにするには ネットワーク遅延を低く抑えるため システムがトラフィックを 効率的に管理できるよう Appデータの適切な 分類が重要です またシステムがネットワーク遅延を 低く抑えられるようにすると Appのフォアグラウンド トラフィックが高速になり ユーザーにとって 最も重要なデータが 迅速に送られます 例を挙げて説明しましょう 多くのAppはグラフィクスや オーディオファイルなどの コンテンツをプリフェッチして 後で使用できるようにします Appが大量のデータを プリフェッチしている場合 ネットワークはこのように 表示されるでしょう ボトルネックキューが いっぱいになる可能性があります この時点でユーザが ネットワークアクティビティ (プロファイルページの 表示など)を開始した場合 このリクエストに対する応答は ネットワークキューの 最後に入れられ プロファイル表示までに 数秒かかることがあります これは優れたユーザー 体験ではありません ではこれらのユーザー以外が 開始したプリフェッチタスクを バックグラウンドとしてマークすると ネットワークにどのような影響があるか 見てみましょう これらの非ユーザーが開始する 転送をバックグラウンドとして マークするとネットワークキューの サイズが大幅に削減され 他のフォアグラウンドデータで 使えるようになります つまり緑のパケットである フォアグラウンドデータは すぐに送られ 迅速で快適な体験が得られます iOS 15および macOS Montereyでは バックグラウンドサービスタイプが 大幅に改善されました バックグラウンドの アップロードとダウンロード用に 新しい輻輳制御アルゴリズムが 追加されました これらの新しいアルゴリズムは ネットワーク遅延を大幅に削減し ユーザー体験を 向上させるだけでなく バックグラウンド転送が 他のトラフィックと ほぼ同じ時間で 終了するようにします ではバックグラウンド サービスタイプを 活用するために採用できる ネットワーキングAPIに ついて見ていきましょう Appがフォアグラウンドにあり 非ユーザーが開始した転送実行中は デフォルトの URLSessionを使い URLリクエストで ネットワークサービスタイプを バックグラウンドに設定します この場合もシステムはネットワーク 遅延を低く抑えられます またNWConnectionの 場合はNWParametersで サービスクラスを バックグラウンドに設定します ユーザーが開始したか どうかにかかわらず 長時間実行される転送を Appが開始した場合は バックグラウンドの URLSessionを作成すると Appが一時停止している場合でも 実行を継続します 時間をかけないタスクの場合は isDiscretionaryプロパティを trueに設定できます これによりシステムは最適な状態で 転送実行まで待機できます ネットワークキューを短く するためにAppが どのように役立つかに ついて説明しました 送信側デバイス自体には別の 遅延源が存在する場合があります 従来ネットワーキングスタックが 使用する送信バッファは 非常に大きなものでした これによりパケットが ネットワークに入る前に 多くの不要な遅延 (秒単位の場合も)が ときどき入ります これは2015年にURLSessionと NWConnectionで 修正されました しかしインターネット上の ほとんどのサーバは Linux上で動作し BSDソケットを使用しています サーバーオペレータに問い合わせて TCP NotSent Low Watermark ソケットオプションで ソースでの遅延の短縮を 確認してください 次のステップでは 最新のネットワーク プロトコルを導入して 複数のラウンド トリップを排除します バックグラウンドモードは アセットのプリフェッチ 一括転送および緊急でない タスクにお使いください 様々なネットワーク条件でApp パフォーマンスをテストします ネットワークリンクコンディショナは それを行うための秀でたツールです ネットワーク遅延を低く抑えると Appの応答性が向上し 全体的なユーザー体験が向上します ご覧いただきありがとうございます WWDCをお楽しみください ♪
-
-
9:28 - Fast open with TCP handshake
/* Allow fast open on the connection parameters */ parameters.allowFastOpen = true let connection = NWConnection(to: endpoint, using: parameters) /* Call send with idempotent initial data before starting the connection */ connection.send(content: initialData, completion: .idempotent) connection.start(queue: myQueue)
-
11:01 - Sockets with fast open
connectx(fd, ..., CONNECT_DATA_IDEMPOTENT | CONNECT_RESUME_ON_READ_WRITE, ...); // delay SYN write(fd, ...); // SYN goes out with first data segment
-
13:35 - Save round-trips when switching networks with Multipath TCP
// Multipath TCP // Save multiple round-trips when switching networks // On URLSessionConfiguration let configuration = URLSessionConfiguration.default configuration.multipathServiceType = .interactive // On NWParameters let parameters = NWParameters.tcp parameters.multipathServiceType = .interactive
-
20:09 - Background service type, App in foreground
//Use default URLSession, set background on URLRequest var request = URLRequest(url: myurl) request.networkServiceType = .background //Set service class on parameters to apply to the NWConnection let parameters = NWParameters.tls parameters.serviceClass = .background
-
20:10 - Time insensitive tasks running in background
//Configure background URL Session lazy var urlSession: URLSession = { let configuration = URLSessionConfiguration.background(withIdentifier: "MySession") configuration.isDiscretionary = true return URLSession(configuration: configuration, delegate: self, delegateQueue: nil) }()
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。