From cf9a876f3e270f665cddddb2a6b75f2be64f8895 Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Wed, 4 Aug 2021 10:22:00 +0900 Subject: Web/Performance 以下のいくつかの文書を更新 (#1686) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 下記の文書を 2021/07/25 時点の英語版に同期更新 - Web/Performance - Web/Performance/How_browsers_work また、下記の文書を新規翻訳 - Web/Performance/Fundamentals --- files/ja/web/performance/fundamentals/index.html | 219 +++++++++++++++++++++ .../web/performance/how_browsers_work/index.html | 82 ++++---- files/ja/web/performance/index.html | 208 +++++++++---------- 3 files changed, 364 insertions(+), 145 deletions(-) create mode 100644 files/ja/web/performance/fundamentals/index.html (limited to 'files/ja/web/performance') diff --git a/files/ja/web/performance/fundamentals/index.html b/files/ja/web/performance/fundamentals/index.html new file mode 100644 index 0000000000..eec0ddf96f --- /dev/null +++ b/files/ja/web/performance/fundamentals/index.html @@ -0,0 +1,219 @@ +--- +title: パフォーマンスの基礎 +slug: Web/Performance/Fundamentals +tags: + - Apps + - Firefox + - Gecko + - Guide + - Performance +translation_of: Web/Performance/Fundamentals +--- +
+

パフォーマンスとは、効率性を意味します。この文書では、オープンウェブアプリの観点から、パフォーマンスとは何か、ブラウザープラットフォームでどのようにパフォーマンスを向上させるか、テストや改善にどのようなツールやプロセスを使用できるかについて一般的な説明をします。.

+
+ +

パフォーマンスとは

+ +

最終的には、ユーザーが知覚したパフォーマンスが唯一のパフォーマンスとなります。ユーザーは、触ったり、動かしたり、話したりして、システムに入力を与えます。その代わり、ユーザーは視覚、触覚、聴覚を通じて出力を知覚します。パフォーマンスとは、ユーザーの入力に応じてシステムが出力するものの品質のことです。

+ +

他の条件が同じであれば、ユーザーが知覚するパフォーマンス (以下、UPP) 以外のターゲットに最適化されたコードは、 UPP に最適化されたコードと競合すると負けてしまいます。ユーザーは、例えば、 1 秒間に 1,000 件しかデータベーストランザクションを処理しないが応答性の高いスムーズに動くアプリの方を、 1 秒間に 100,000,000 件のデータベーストランザクションを処理するカクカクした応答性の低いアプリよりも好みます。もちろん、他の指標を最適化することは決して無意味ではありませんが、実際の UPP ターゲットが最優先です。

+ +

以下の節では、必須のパフォーマンス指標を指摘し、説明します。

+ +

応答性

+ +

応答性とは、ユーザーの入力に応じてシステムがどれだけ速く出力 (複数の場合もある) を行うかを意味します。例えば、ユーザーが画面をタップすると、ピクセルが特定の方法で変化することを期待します。この操作の場合、応答性の指標は、タップしてからピクセルが変化するまでの経過時間となります。

+ +

応答性には、複数の段階のフィードバックが含まれることがあります。アプリケーションの起動は、特に重要なケースの一つで、詳しくは後述します。

+ +

応答性が重要なのは、人は無視されるとイライラしたり怒ったりするからです。アプリはユーザーの入力に応答しない間、ユーザーを無視していることになります。

+ +

フレームレート

+ +

フレームレートとは、システムがユーザーに表示するピクセルを変化させる速度のことです。例えば、毎秒 10 フレームのゲームよりも、毎秒 60 フレームのゲームの方が好きだというのは、理由を説明できなくても、誰もが知っている概念です。

+ +

フレームレートは「サービスの質」の指標としても重要です。コンピューターのディスプレイは、現実を模倣した光子をユーザーの目に届けることで、ユーザーの目を「欺く」ように設計されています。例えば、文字が印刷された紙は、光子をあるパターンでユーザーの目に反射させます。リーダーアプリは、ピクセルを操作することで、同じようなパターンで光子を放出し、ユーザーの目を「騙す」のです。

+ +

脳は考えるとき、動きはギクシャクしたバラバラなものではなく、滑らかに連続して更新されるものだと考えます。 (ストロボはそれを逆手に取り、脳の入力を奪って離散的な現実を錯覚させるから面白いのです)。コンピューターのディスプレイでは、フレームレートが高ければ高いほど、より忠実に現実を再現することができます。

+ +
+

: 人間は通常、60Hz以上のフレームレートの違いを知覚することができません。そのため、最近の電子ディスプレイは、60Hzで更新するように設計されています。例えばハチドリには、テレビが途切れ途切れで非現実的に見えることでしょう。

+
+ +

メモリーの使用

+ +

メモリーの使用量も重要な指標です。応答性やフレームレートとは異なり、ユーザーはメモリー使用量を直接知覚することはありませんが、メモリー使用量は「ユーザーの状態」に近いものです。理想的なシステムでは、ユーザーの状態を常に 100% 維持することができます。システム内のすべてのアプリケーションは同時に実行され、すべてのアプリケーションは、ユーザーが最後にアプリケーションを操作したにユーザーが設定した状態を維持します (アプリケーションの状態はコンピュータのメモリーに保存されているため、近似値になるのです)。

+ +

このことから、重要ではあるが直感的ではない副産物が得られます。設計の優れたシステムは、空きメモリー量を最大化しません。メモリーは資源であり、空きメモリーは使われていない資源であるからです。むしろ、設計の優れたシステムは、ユーザーの状態を維持するために可能な限り多くのメモリーを使用し、かつ他の UPP 目標を満たすように最適化されています。

+ +

これは、システムがメモリーを浪費すべきだという意味ではありません。システムがある特定のユーザーの状態を維持するために必要以上のメモリーを使用すると、システムは他のユーザーの状態を維持するために使用できる資源を浪費していることになります。実際には、すべてのユーザーの状態を維持できるシステムはありません。ユーザーの状態に賢くメモリーを割り当てることは、以下で詳しく説明する重要な問題です。

+ +

電力使用量

+ +

ここで解説する最後の指標は、電力使用量です。メモリー使用量と同様に、ユーザーは、端末が他のすべての UPP 目標を維持できる時間という形で、電力使用量を間接的にしか認識しません。 UPP 目標を達成するためには、システムは必要最小限の電力しか使用しないようにする必要があります。

+ +

この文書の残りの部分では、これらの指標の観点からパフォーマンスについて説明します。

+ +

プラットフォームのパフォーマンスの最適化

+ +

この節では、 Firefox/Gecko が、すべてのアプリケーションのレベルよりも下位で、一般的にどのようにパフォーマンスに貢献しているかを簡単に説明します。開発者やユーザーの視点から、「プラットフォームは何をしてくれるのか?」という問いに答えます。

+ +

ウェブ技術

+ +

ウェブプラットフォームには多くのツールが用意されていますが、中には特定の仕事に適したものもあります。アプリケーションロジックはすべて JavaScript で書かれています。グラフィックの表示には、 (高水準の宣言型言語である) HTML や CSS を使用するか、低レベルの命令型インターフェースである {{ htmlelement("canvas") }} 要素 (WebGL を含む) を使用します。 HTML/CSS と Canvas の「中間」に位置するのが SVG で、両者の利点を兼ね備えています。

+ +

HTML や CSS は、フレームレートやピクセルレベルでのレンダリング制御を犠牲にして、生産性を大幅に向上させます。テキストや画像は自動的に再フローされ、 UI 要素には自動的にシステムのテーマが適用されます。また、このシステムは、様々な解像度のディスプレイや右書きの言語など、開発者が最初に思いつかないような使用方法に「組み込み」で対応します。

+ +

canvas 要素は、開発者が直接描画できるピクセルバッファーを提供します。これにより、開発者はピクセルレベルでレンダリングを制御し、フレームレートを正確に制御することができますが、複数の解像度や方向、右書きの言語などに対応する必要があります。開発者は、おなじみの 2D 描画 API か、 OpenGL ES 2.0 をほぼ踏襲した「金属に近い」バインディングである WebGL を使用してキャンバスに描画します。

+ +
+

: Firefox OS は、 HTMLCSSJavaScript などのウェブ技術で作られたアプリに最適化されています。一握りの基本的なシステムサービスを除いて、 Firefox OS で動作するすべてのコードはウェブアプリと Gecko エンジンから来ています。 OS のウィンドウマネージャも HTML、CSS、JavaScript で書かれています。コアとなる OS とアプリケーションは同じウェブ技術で構築されているため、これらの技術がどのように機能するかが重要になります。そこには「逃げ道」はありません。これは開発者にとって大きなメリットです。なぜなら、サードパーティのアプリケーションは、 OS が独自に行ったすべての最適化の恩恵を受けることができるからです。プリインストールされたコードだけが利用できる「魔法のパフォーマンスソース」はありません。 Firefox OS に関する詳細は、 Firefox OS のパフォーマンステストをご覧ください。

+
+ +

Gecko のレンダリング

+ +

Gecko の JavaScript エンジンは、実行時 (JIT) コンパイルに対応しています。これにより、アプリケーションロジックは、Java 仮想マシンのような他の仮想マシンと同等の性能を発揮し、場合によっては「ネイティブコード」に近い性能を発揮します。

+ +

HTML、CSS、Canvas を支える Gecko のグラフィックパイプラインは、いくつかの方法で最適化されています。 Gecko の HTML/CSS レイアウトおよびグラフィックコードは、スクロールなどの一般的なケースでは、無効化や再描画を削減しますが、開発者はこのサポートを「無料」で受けることができます。 Gecko が「自動的に」描画したり、 canvas へアプリケーションが「手動で」描画したりするピクセルバッファーは、ディスプレイのフレームバッファーに描画される際のコピーを最小限に抑えます。これは、中間サーフェスがオーバーヘッドになるような場所 (他の多くのオペレーティングシステムにおけるアプリケーションごとの「バックバッファー」など) を避け、コンポジターハードウェアが直接アクセスできるグラフィックバッファー用の特別なメモリーを使用することで実現されています。複雑なシーンのレンダリングには、端末の GPU を使用して最大のパフォーマンスを発揮します。電力消費を抑えるために、シンプルなシーンは専用の合成ハードウェアを使ってレンダリングし、 GPU はアイドルまたはオフにしています。

+ +

リッチアプリケーションでは、完全な静的コンテンツは例外です。リッチアプリケーションでは、アニメーションやトランジション効果のある動的コンテンツを使用します。トランジションやアニメーションは、アプリケーションにとって特に重要です。開発者は、 CSS を使用することで、複雑な動作をシンプルで高レベルな構文で宣言することができます。また、 Gecko のグラフィックパイプラインは、一般的なアニメーションを効率的に描画するように高度に最適化されています。良くあるアニメーションは、システムコンポジターにオフロードされ、パフォーマンスと電力効率に優れた方法でレンダリングされます。

+ +

アプリの起動時のパフォーマンスは、実行時のパフォーマンスと同じくらい重要です。 Gecko は、 Web 全体を含むさまざまなコンテンツを効率的に読み込むように最適化されています。並列 HTML 解析、再フローと画像デコーディングのインテリジェントなスケジューリング、巧妙なレイアウトアルゴリズムなど、コンテンツを対象とした長年の改良は、Firefox でのウェブアプリケーションの改良にも同様に反映されます。

+ +
+

: 起動時のパフォーマンスをさらに向上させるための Firefox OS の仕様についての詳細は、 Firefox OS パフォーマンステストを参照してください。

+
+ +

アプリケーションのパフォーマンス

+ +

この節では、「どうしたらアプリを高速にできるのか」という開発者の問いのためのものです。

+ +

起動時のパフォーマンス

+ +

アプリケーションの起動は、一般的に 3 つのイベントで構成されています。

+ + + +

高速な起動の鍵となるのは、 2 つのことを念頭に置くことです。 UPP がすべてであること、そして上記のユーザーが知覚する各イベントには「クリティカルパス」が存在することです。クリティカルパスとは、まさに、そのイベントを発生させるために実行しなければならないコードのことです。

+ +

例えば、アプリケーションの最初のフレームを視覚的に描くためには、いくつかの HTML と、その HTML にスタイル付けする CSS で構成されます。

+ +
    +
  1. HTML を解釈する必要がある
  2. +
  3. その HTML の DOM を構築する必要がある
  4. +
  5. DOM の一部にある画像などのリソースを読み込み、デコードする必要がある
  6. +
  7. CSS のスタイルをその DOM に適用する必要がある
  8. +
  9. スタイル付けした文書を再フローさせる必要がある
  10. +
+ +

このリストのどこにも、「一般的でないメニューに必要な JS ファイルの読み込み」や「ハイスコアリスト用の画像の取得とデコード」などは含まれていません。これらの作業項目は、最初のフレームを描くためのクリティカルパスには含まれていません。

+ +

当たり前のようですが、ユーザーが認識する起動イベントに早く到達するためには、クリティカルパス上のコードだけを実行することが主な「コツ」です。その場面を単純化することで、クリティカルパスを短縮します。

+ +

ウェブプラットフォームは非常にダイナミックです。 JavaScript は動的に型付けされる言語であり、ウェブプラットフォームではコード、HTML、CSS、画像などのリソースを動的に読み込むことができます。これらの機能を利用して、起動後しばらくしてから不要なコンテンツを「遅延して」読み込むことで、クリティカルパスから外れた作業を先送りすることができます。

+ +

起動を遅らせるもう 1 つの問題は、リクエストに対するレスポンス (データベースのロードなど) を待つことで発生するアイドルタイムです。この問題を避けるために、アプリケーションは起動時にできるだけ早くリクエストを発行する必要があります (これを「フロントローディング」と呼びます)。そうすれば、後でデータが必要になったとき、うまくいけばすでに利用可能で、アプリケーションは待つ必要がありません。

+ +
+

: 起動時のパフォーマンスを向上させるための詳しい情報は、起動時のパフォーマンスを最適化するをご覧ください。

+
+ +

また、ローカルにキャッシュされた静的なリソースは、高レイテンシー、低帯域幅のモバイルネットワークを介して取得された動的なデータよりもはるかに速く読み込まれることに注意してください。ネットワークへのリクエストは、アプリケーションの早期起動のためのクリティカルパスであってはなりません。ローカルキャッシュ/オフラインアプリケーションは、サービスワーカーによって実現できます。その方法については、 サービスワーカーで PWA をオフライン対応させる を参照してください。

+ +

フレームレート

+ +

高フレームレートを実現するためにまず重要なのは、適切な道具を選ぶことです。静止画やスクロール、アニメーションの頻度が少ないコンテンツの実装には、 HTML と CSS を使用します。レンダリングを厳密にコントロールする必要があり、テーマ性を必要としないゲームのように、高度に動的なコンテンツを実装する場合は、キャンバスを使用します。

+ +

キャンバスで描かれたコンテンツでは、フレームレートの目標値を達成できるかどうかは、開発者次第です。

+ +

HTML と CSS のコンテンツでは、適切なプリミティブを使用することが高フレームレートへの道となります。 Firefox は任意のコンテンツをスクロールするために高度に最適化されているため、通常はこの点を気にする必要はありません。しかし、 CSS の放射状グラデーションの代わりに静的なレンダリングを使用するなど、速度のために汎用性や品質を犠牲にすると、スクロールのフレームレートが目標値を超えてしまうことがよくあります。 CSS のメディアクエリーを使えば、こうした妥協を必要とする端末だけに制限することができます。

+ +

多くのアプリケーションでは、「ページ」や「パネル」を使ったトランジションやアニメーションが使われています。例えば、ユーザーが「設定」ボタンをタップすると、アプリケーションの設定画面に遷移したり、設定メニューが「ポップアップ」したりします。 Firefox は、以下のようなシーンの遷移やアニメーションに高度に最適化されています。

+ + + +

これらのガイドラインに従った遷移やアニメーションは、システムコンポジターにオフロードされ、最大限効率的に動作します。

+ +

メモリーと電力の使用量

+ +

メモリーと電力使用量の改善は、スタートアップの高速化と同じような問題です。必要のない作業をしたり、普段使わない UI リソースをダラダラとロードしたりしてはいけません。効率的なデータ構造を使用し、画像などのリソースをしっかりと最適化しましょう。

+ +

最近の CPU は、ほとんどアイドル状態の時に低消費電力モードに入ることができます。常にタイマーを作動させたり、不要なアニメーションを実行し続けるアプリケーションは、 CPU が低電力モードに入るのを妨げます。電力効率の良いアプリケーションは、そのようなことをしてはいけません。

+ +

アプリケーションがバックグラウンドに送られると、その文書に対して {{event("visibilitychange")}} イベントが発行されます。このイベントは開発者の味方です。アプリケーションはこのイベントに耳を傾けるべきです。バックグラウンドに送られたときに、アプリケーションが読み込まれたリソースをできるだけ多く手放すと、メモリー使用量が少なくて済み、 Firefox OS の場合、廃棄される可能性も低くなります (以下のメモを参照)。これはつまり、 (すでに実行されているため) 「起動」が速く、 UPP が良いことを意味します。

+ +
+

: 前述のとおり、 Firefox OS はできる限り多くのアプリケーションを同時に実行するようにしていますが、通常は端末のメモリーが不足したときにアプリケーションを破棄しなければならないことがあります。Firefox OS がどのようにメモリー使用量を管理し、メモリー不足の問題が発生したときにアプリケーションを終了するかについての詳細は、「Debugging out of memory errors on Firefox OS」を参照してください。

+
+ +

アプリケーションのパフォーマンスのためのコーディングのコツ

+ +

以下の実用的なヒントは、前述のアプリケーションのパフォーマンス要因の 1 つまたは複数を改善するのに役立ちます。

+ +

CSS アニメーションとトランジションを使用する

+ +

一部のライブラリーの animate() 関数は、おそらく現在、パフォーマンスが悪い数多くの技術 (例えば {{domxref("WindowOrWorkerGlobalScope.setTimeout")}} や top/left による位置指定) を使用しています。代わりに CSS アニメーションを使用してください。多くの場合、実際には CSS トランジションを使って実現することができます。ブラウザーはこれらの効果を最適化するように設計されており、 GPU を使用してプロセッサーのパフォーマンスへの影響を最小限に抑えながらスムーズに処理することができるため、うまく機能します。もう一つの利点は、標準化された構文を使って、アプリの他のルック&フィールと一緒に CSS でこれらの効果を定義できることです。

+ +

CSS アニメーションでは、 キーフレームを使って効果を細かく制御することができます。また、アニメーション処理中に発生するイベントを監視して、アニメーション処理中の特定のポイントで実行する必要のある他のタスクを処理することもできます。これらのアニメーションは、 {{cssxref(":hover")}}, {{cssxref(":focus")}}, {{cssxref(":target")}} を使ったり、親要素に動的にクラスを追加したり削除したりすることで、簡単に起動することができます。

+ +

アニメーションをその場で作成したり、 JavaScript で修正したりしたい場合は、 James Long 氏が CSS-animations.js というシンプルなライブラリーを作成していますので、そちらをご利用ください。

+ +

CSS 変換を使用する

+ +

コンテンツの位置やスケールなどを調整するのに、絶対位置を調整したり、すべての計算を自分で行ったりする代わりに、 CSS の {{cssxref("transform")}} プロパティを使用しましょう。その理由は、繰り返しになりますが、ハードウェアアクセラレーションです。ブラウザーはこれらの作業を GPU で行い、 CPU に他の処理をさせることができます。

+ +

さらに、変換は、他では得られない機能を提供します。 2D 空間の要素を変換するだけでなく、 3 次元に変換したり、斜めにしたり、回転させたりすることができます。 Paul Irish 氏は、パフォーマンスの観点から見た translate() の利点を詳しく分析しています。しかし、一般的には、 CSS アニメーションを使用する場合と同じメリットがあります。つまり、仕事に適したツールを使用し、最適化はブラウザーに任せることができるのです。また、要素の位置を簡単に拡張できる方法を使用しています。 topleft の位置指定で変換をシミュレートする場合は、多くの追加コードが必要になります。もうひとつの利点は、 canvas 要素で作業するのと同じだということです。

+ +
+

: プラットフォームによっては、 CSS アニメーションでハードウェアアクセラレーションを利用したい場合、 translateZ(0.1) 変換を割り当てる必要があります。前述のとおり、パフォーマンスが向上しますが、メモリー消費の問題もあります。テストをして、自分のアプリケーションに最適な方法を見つけてみてはいかがでしょうか。

+
+ +

requestAnimationFrame()setInterval() の代わりに使用する

+ +

{{domxref("WindowOrWorkerGlobalScope.setInterval")}} の呼び出しは、現在の状況下で可能かどうかわからない推定フレームレートでコードを実行します。このコードは、ブラウザーが実際に描画していない間、つまりビデオハードウェアが次の表示サイクルに達していない間にも、結果をレンダリングするようブラウザーに指示します。これはプロセッサー時間を浪費し、ユーザーの端末のバッテリー寿命を縮めることにもつながります。

+ +

その代わりに、 {{domxref("window.requestAnimationFrame()")}} を使うようにしましょう。これは、ブラウザーがアニメーションの次のフレームを作り始める準備ができるまで待機し、ハードウェアが実際に何も描画しない場合は無視します。この API のもう一つの利点は、アプリが画面上に表示されていない間はアニメーションが実行されないことです (バックグラウンドで他のタスクが動作している場合など)。これにより、バッテリーの消費を抑え、ユーザーが夜空に向かってあなたの名前を罵るのを防ぐことができます。

+ +

イベントを即時にする

+ +

アクセシビリティに配慮した古いタイプのウェブ開発者は、キーボード入力二も対応する click イベントが大好きです。モバイル端末では、これらのイベントは遅すぎます。代わりに {{event("touchstart")}} と {{event("touchend")}} を使うべきです。これらのイベントには、アプリの操作を鈍くする遅延がないからです。最初にタッチ対応のテストを行えば、アクセシビリティも犠牲にすることはありません。例えば、 Financial Times は、そのために fastclick というライブラリーを使用しており、これを利用することができます。

+ +

インターフェイスをシンプルに保つ

+ +

HTML5 アプリのパフォーマンスに関する大きな問題のひとつに、たくさんの DOM 要素を移動させるとすべてが遅くなるということがあります。見た目をシンプルにして、ドラッグ&ドロップでプロキシー要素を移動させるようにすると非常に有効です。

+ +

たとえば、長い要素のリスト (ツイートとします) がある場合、それらをすべて移動させてはいけません。代わりに、表示されているものと、現在表示されているツイートのセットの両側にいくつかあるものだけを DOM ツリーに残します。残りは隠すか削除します。データを DOM にアクセスするのではなく、 JavaScript のオブジェクトに保持することで、アプリのパフォーマンスが大幅に向上します。表示は、データそのものではなく、データのプレゼンテーションだと考えてください。だからといって、 HTML をそのままソースとして使ってはいけないというわけではありません。 HTML を一度読み込んでから 10 個の要素をスクロールさせ、表示されていない 100 個の要素を動かすのではなく、結果リストの中の自分の位置に応じて最初と最後の要素の内容を変えればいいのです。ゲームでは、スプライトにも同じことが言えます。その代わりに、画面外にスクロールした要素を新しいものが入ってきたときに再利用します。

+ +

一般的なアプリケーションのパフォーマンス分析

+ +

Firefox や Chrome などのブラウザーには、ページの表示速度が遅いことを診断するためのツールが組み込まれています。特に、 Firefox のネットワークモニターは、ページ上のそれぞれのネットワークリクエストがいつ発生し、どれくらいの規模で、どれくらいの時間がかかっているかを正確に時系列で表示します。

+ +

Firefox のネットワークモニターが、リクエストの取得、複数のファイル、各リソースの読み込みにかかった時間をグラフで表示しているところ。

+ +

ページに実行に時間がかかる JavaScript コードが含まれている場合、 JavaScript プロファイラーは最も遅いコードの行を特定します。

+ +

Firefox の JavaScript プロファイラーが完成したプロファイル 1 を表示しているところ。

+ +

Gecko 内蔵のプロファイラー は、プロファイラーの実行中にブラウザーのコードのどの部分がゆっくりと動作しているかについて、さらに詳細な情報を提供する非常に便利なツールです。これは使用方法が少し複雑ですが、多くの有用な詳細情報を提供してくれます。

+ +

Gecko 内蔵プロファイラーウィンドウが多くのネットワーク情報を表示しているところ。

+ +
+

: Android のブラウザーで Firefox を起動し、リモートデバッグを有効にすることで、これらのツールを使用することができます。

+
+ +

特に、モバイルブラウザーでは、数十から数百のネットワークリクエストに時間がかかります。また、大きな画像や CSS グラデーションの描画にも時間がかかることがあります。大きなファイルのダウンロードは、高速なネットワークであっても時間がかかることがあります。これは、モバイルハードウェアの速度が遅すぎて、利用可能なすべての帯域幅を活用できない場合があるためです。モバイルウェブのパフォーマンスに関する一般的なヒントについては、 Maximiliano Firtman 氏の Mobile Web High Performance の談話をご覧ください。

+ +

テストケースとバグの報告

+ +

Firefox や Chrome の開発者ツールで問題が解決しない場合や、ウェブブラウザーが原因と思われる場合は、問題を最大限に分離した縮小版のテストケースを提供してみてください。それが問題の診断に役立つことがよくあります。

+ +

HTML ページの静的なコピー (埋め込まれている画像、スタイルシート、スクリプトを含む) を保存、読み込みすることで問題を再現できるかどうかを確認してください。問題が再現できれば、静的ファイルを編集して個人情報を削除し、他の人に送って助けを求めてください (例えば、 Bugzilla レポートを提出するか、サーバーでホスティングして URL を共有してください)。また、上述のツールを使って収集したプロファイリング情報も共有してください。

diff --git a/files/ja/web/performance/how_browsers_work/index.html b/files/ja/web/performance/how_browsers_work/index.html index f936eb14a7..9483fed99b 100644 --- a/files/ja/web/performance/how_browsers_work/index.html +++ b/files/ja/web/performance/how_browsers_work/index.html @@ -1,5 +1,5 @@ --- -title: ページの生成:ブラウザーはどのように動作するか +title: 'ページの生成: ブラウザーの動作の仕組み' slug: Web/Performance/How_browsers_work tags: - Browsers @@ -15,27 +15,27 @@ tags: - render translation_of: Web/Performance/How_browsers_work --- -

ユーザーは、読み込みが速く、スムーズにインタラクションできるコンテンツを、ウェブで体験することを求めています。したがって、開発者はこれらふたつの目標を達成するために努力しなければいけません。

+

ユーザーは、読み込みが速く、スムーズに操作できるコンテンツを、ウェブで体験することを求めています。したがって、開発者はこれらふたつの目標を達成するために努力しなければいけません。

どうやって性能そして体感性能を改善するか理解するためには、ブラウザーがどのように動作するかを理解することが役に立ちます。

-

概要

+

概要

-

速いサイトはより良いユーザー体験をもたらします。ユーザーは読み込みが速く、スムーズにインタラクションできるコンテンツを体験することを求め、期待しています。

+

速いサイトはより良いユーザー体験をもたらします。ユーザーは読み込みが速く、スムーズに操作できるコンテンツを体験することを求め、期待しています。

ウェブの性能における 2 つの主要な課題は、レイテンシーに関する諸問題と、多くの場合ブラウザーはシングルスレッドであるという事実に関する諸問題を理解することです。

レイテンシーは、速い読み込みを実現するために克服しなければいけない一番の脅威です。読み込みを速くしようとする開発者のゴールは、リクエストされた情報をできる限り速く送信すること、または少なくともとても速いように見せることです。ネットワークのレイテンシーは、バイト情報をコンピューターまで送信するのにかかる時間のことです。ウェブの性能は、ページの読み込みを出来る限り速くするよう私たちが何をするかにかかっています。

-

多くの場合、ブラウザーはシングルスレッドだと考えられます。スムーズなインタラクションを実現しようとする開発者のゴールは、滑らかなスクロール、タッチ操作への反応など、期待通りのサイトのインタラクションを実現することです。メインスレッドが全ての処理を時間内に完了し、その上でユーザーのインタラクションを常にハンドリングできるよう保証するために、描画時間が鍵となります。ブラウザーがシングルスレッドであることによる特性を理解し、メインスレッドの責務を最小限に抑え、可能かつ適切な場合に、描画のスムーズさとインタラクションへの即時の反応を実現することで、ウェブの性能が改善されます。

+

多くの場合、ブラウザーはシングルスレッドだと考えられます。スムーズな操作を実現しようとする開発者のゴールは、滑らかなスクロール、タッチ操作への反応など、期待通りのサイトの操作を実現することです。メインスレッドが全ての処理を時間内に完了し、その上でユーザーの操作を常にハンドリングできるよう保証するために、描画時間が鍵となります。ブラウザーがシングルスレッドであることによる特性を理解し、メインスレッドの責務を最小限に抑え、可能かつ適切な場合に、描画のスムーズさと操作への即時の反応を実現することで、ウェブの性能が改善されます。

- +

ナビゲーションはウェブページを読み込むための最初の一歩です。ユーザーが URL をアドレスバーに入力したり、リンクをクリックしたり、またはフォームを送信したり、ページをリクエストするたびごとにナビゲーションが発生します。

ウェブの性能における目標の 1 つは、ナビゲーションが完了するまでの時間を最小限にすることです。理想的な条件下において、一般的にこの時間が長すぎることはありませんが、レイテンシーと帯域幅が遅延を引き起こす邪魔者になる場合があります。

-

DNS ルックアップ

+

DNS ルックアップ

ウェブページへのナビゲーションの最初の一歩は、ページのアセットがどこにあるか見つけることです。https://example.com へアクセスする場合、その HTML のページは IP アドレスが 93.184.216.34 のサーバーに存在します。これまでに一度もそのサイトを訪れたことがなかった場合、DNS ルックアップが必要になります。

@@ -43,27 +43,27 @@ translation_of: Web/Performance/How_browsers_work

DNS ルックアップは、一般的に、1 回のページ読み込みの中でホスト名ごとに 1 回だけ必要になります。しかし、DNS ルックアップは要求されたページが参照するユニークなホストネームそれぞれに対して実行が必要です。必要なフォントや画像、スクリプト、広告、メトリクスのそれぞれが異なるホスト名を持っている場合は、それぞれに対して DNS ルックアップが必要です。

-

Mobile requests go first to the cell tower, then to a central phone company computer before being sent to the internet

+

携帯電話のリクエストは、まずセルタワーに送られ、次に電話会社の中央コンピューターに送られた後、インターネットに送信される

これはとくにモバイルネットワークにおいて性能上の問題になる可能性があります。ユーザーがモバイルネットワークを利用している場合、DNS ルックアップは、権威 DNS サーバーへ到達するために、電話機から基地局へ送信される必要があります。電話機と基地局、そしてネームサーバー間の距離によって重大な遅延が発生する場合があります。

-

TCP ハンドシェイク

+

TCP ハンドシェイク

IP アドレスが判明すると、ブラウザーは {{glossary('TCP handshake','TCP 3 ウェイハンドシェイク')}}を通じてサーバーとのコネクションを設定します。この仕組みは、通信を意図する 2 つの主体が—この場合はブラウザーとウェブサーバーが—、データを送信する前に、多くの場合 {{glossary('HTTPS')}} を用いて、ネットワーク TCP ソケットコネクションのパラメーターを交換できるよう設計されています。

TCP の 3 ウェイハンドシェイクは、しばしば、"SYN-SYN-ACK"、より正確には SYN、SYN-ACK、ACK と呼ばれます。これは 2 つのコンピューターの間で TCP のセッションを開始するために、TCP によって 3 つのメッセージが送受信されることを表します。つまり、これはそれぞれのサーバーの間で 3 回以上のメッセージのやりとりが必要であり、そのためのリクエストが生成されなければいけないことを意味しています。

-

TLS ネゴシエーション

+

TLS ネゴシエーション

HTTPS によって確立される安全なコネクションでは、もう 1 つのハンドシェイクが必要です。このハンドシェイク、より正確に言うと {{glossary('TLS')}} ネゴシエーションは、通信の暗号化に使用する暗号の種類を決定し、サーバーを認証し、実際のデータ送信が始まる前に安全な通信の準備を整えます。この処理は、コンテンツのリクエストを実際に送信する前に、さらに 3 回のラウンドトリップを必要とします。

-

The DNS lookup, the TCP handshake, and 5 steps of the TLS handshake including clienthello, serverhello and certificate, clientkey and finished for both server and client.

+

DNS ルックアップ、TCP ハンドシェイク、そして TLS ハンドシェイクの 5 つのステップ (clienthello、serverhello、証明書、clientkey、サーバーとクライアントの両方の完了)。

通信を安全にするためにページ読み込みの時間が追加されますが、ブラウザーとサーバーの間で送信されるデータが第三者に解読されないという安全な通信は、レイテンシーに見合う価値があるものです。

8 回のラウンドトリップを経て、ブラウザーはようやくリクエストを送ることができます。

-

レスポンス

+

レスポンス

ウェブサーバーへのコネクションが確立されると、ブラウザーはユーザーに代わって最初の HTTP GET リクエストを送信します。ウェブサイトであれば、多くの場合その対象は HTML ファイルです。リクエストを受け取ったサーバーは、適当なレスポンスヘッダーと HTML のコンテンツを返します。

@@ -89,21 +89,21 @@ translation_of: Web/Performance/How_browsers_work

上記のサンプルコードでは、リクエストされたコンテンツは明らかに 14kB より小さいですが、後述するように、リンクされたリソースは、ブラウザーのパース処理がそのリンクにたどり着くまでリクエストされることはありません。

-

TCP スロースタート / 14kB ルール

+

TCP スロースタート / 14kB ルール

最初の応答パケットは 14kB になります。これは、{{glossary('TCP slow start','TCP スロースタート')}}の一部で、ネットワークコネクションの速度を制御するアルゴリズムの影響です。スロースタートは、ネットワークの最大の帯域幅が確定するまで徐々に送信するデータ量が増やします。

{{glossary('TCP slow start','TCP スロースタート')}}において、サーバーは最初のパケットを受信した後、次のパケットのサイズを 28kB に倍増させます。さらに後続のパケットについて事前に決めた上限に達するか、ネットワークの輻輳を検知するまでサイズを増やします。

-

TCP slow start

+

TCP スロースタート

最初のページ読み込みに関する 14kB ルールを聞いたことがあった場合、それは TCP スロースタートが理由です。そしてこれはウェブの性能の最適化が最初の 14kB にフォーカスする理由でもあります。TCP スロースタートは、ネットワークの輻輳を防ぎ、ネットワーク性能に対して適正なデータ転送速度を徐々に探り出します。

-

輻輳制御

+

輻輳制御

サーバーが TCP パケットとしてデータを送信する一方で、ユーザー側のクライアントは確認応答、ACK を返してデータが配送されたことを確認します。コネクションには、ハードウェアやネットワークの条件によって許容量上の制限があります。サーバーが大きすぎるパケットを速すぎる速度で送信した場合、破棄されるでしょう。つまり、確認応答がない場合があるということです。サーバーはこれを missing ACK として処理します。輻輳制御アルゴリズムは、パケットを送信して確認応答を受け取るこのフローを使って送信レート (send rate) を決定します。

-

パース処理

+

パース処理

データの最初のかたまりを受け取ると、ブラウザーは受信した情報のパース処理を始めることができます。{{glossary('speculative parsing', 'パース処理')}}は、ネットワークから受信したデータを {{glossary('DOM')}} と {{glossary('CSSOM')}} に変換するステップです。DOM と CSSOM は、レンダラーがページを画面へ描画するために利用されます。

@@ -111,7 +111,7 @@ translation_of: Web/Performance/How_browsers_work

ブラウザーは、リクエストしたページの HTML が最初の 14kB のパケットより大きかった場合でも、手元にあるデータに基づいてパース処理を開始し、サイトを描画しようとします。これは、ウェブの性能を最適化する時にに、ブラウザーがページの描画を始めるために必要なすべてのデータ、あるいは少なくともページのテンプレート (最初の描画に必要となる CSS と HTML) を最初の 14kB に含めることが重要となる理由です。何か 1 つでも画面に描画を行うには、その前に HTML と CSS、JavaScript がパースされなければいけません。

-

DOM ツリーの構築

+

DOM ツリーの構築

クリティカルレンダリングパスの 5 つのステップを説明します。

@@ -119,11 +119,11 @@ translation_of: Web/Performance/How_browsers_work

DOM ツリーはドキュメントのコンテンツを表します。<html> 要素は最初のタグであり、ドキュメントツリーのルートノードとなります。ツリーには、異なるタグ同士の関係と階層構造が反映されます。他のタグの中にネストされたタグは子要素となります。DOM ノードの数が増えるほど、DOM ツリーの構築にかかる時間は長くなります。

-

The DOM tree for our sample code, showing all the nodes, including text nodes.

+

サンプルコードの DOM ツリーで、テキストノードを含むすべてのノードが表示されています。

パーサーが画像のようなノンブロッキングリソースを発見した場合、ブラウザーはそのリソースをリクエストし、そのままパース処理を継続します。CSS ファイルに遭遇した場合もパース処理を継続できます、しかし  async または defer 属性がない <script> タグはレンダリングをブロックし、HTML のパース処理を停止します。ブラウザーのプリロードスキャナーがブロックの時間を減らしますが、それでも過度のスクリプトの使用は重大なボトルネックになり得ます。

-

プリロードスキャナー

+

プリロードスキャナー

ブラウザーが DOM ツリーを構築する間はそのプロセスがメインスレッドを占有します。その間にプリロードスキャナーが処理可能なコンテンツをパースし、CSS や JavaScript、ウェブフォントのような優先度の高いリソースのリクエストを行います。プリロードスキャナーのおかげで、リクエストするべき外部リソースへの参照をパーサーが見つけるのを待たなくて良くなります。バックグラウンドでリソースを取得するため、メインの HTML パーサーが該当のアセットにたどり着いた時には、すでにそれらのリソースが転送中あるいはダウンロード済みになっています。プリロードスキャナーによる最適化によりブロッキングを減らすることができます。

@@ -137,7 +137,7 @@ translation_of: Web/Performance/How_browsers_work

CSS の取得は HTML のパース処理あるいはダウンロードをブロックしません。しかし JavaScript の実行をブロックします。その理由は、しばしば JavaScript が CSS プロパティの要素への影響を問い合わせるために使われるからです。

-

CSSOM の構築

+

CSSOM の構築

クリティカルレンダリングパスの 2 つめのステップは CSS を処理して CSSOM ツリーを構築することです。CSS のオブジェクトモデルは DOM によく似ています。DOM と CSSOM はどちらもツリー構造です。この 2 つは独立したデータ構造を持ちます。ブラウザーは、CSS のルールをブラウザーが理解できるスタイルのマップに変換します。ブラウザーは CSS のルールセットを読み取り、CSS セレクターにもとづいて、親、子、兄弟の関係から構成されるノードのツリーを生成します。

@@ -147,23 +147,23 @@ translation_of: Web/Performance/How_browsers_work

CSSOM の構築はとても高速であるため、現在の開発者ツールはそれ自体をユニークな色で表示しません。その代わりに、開発者ツールの「スタイルの再計算」は、CSS を解析して CSSOM ツリーを構築し、再帰的にスタイルを計算するトータルの時間を表示します。ウェブの性能の最適化の観点から言うと、CSSOM を生成するトータルの時間は一般的に1回の DNS ルックアップにかかる時間よりも少ないため、それほどの苦労はないと言えます。

-

その他の処理

+

その他の処理

-

JavaScript のコンパイル

+

JavaScript のコンパイル

CSS がパースされ、CSSOM が生成される間、JavaScript ファイルを含む他のアセットが(プリロードスキャナーによって)ダウンロードされます。JavaScript は、インタープリターに処理され、コンパイル、パース処理を経て実行されます。スクリプトはパース処理によって抽象構文木に変換されます。いくつかのブラウザーエンジンは、{{glossary('Abstract Syntax Tree', '抽象構文木')}}をインタープリターへ引き渡し、メインスレッドで実行されるバイトコードを出力します。これが JavaScript のコンパイル処理に当たります。

-

アクセシビリティツリーの構築

+

アクセシビリティツリーの構築

ブラウザーはコンテンツを理解し翻訳する補助機器で使用されるアクセシビリティツリーも構築します。アクセシビリティオブジェクトモデル (AOM) は補助機器向けの DOM のようなものです。ブラウザーは、DOM が更新されるとアクセシビリティツリーも更新します。アクセシビリティツリーは補助機能それ自体からは変更できません。

AOM が構築されるまで、スクリーンリーダーでコンテンツにアクセスできません。

-

レンダリング

+

レンダリング

-

レンダリングのステップは、スタイル、レイアウト、ペイント、そしてコンポジットで構成されます。パースのステップで作成された CSSOM と DOM のツリーはレンダーツリーの形式へと組み合わされ、すべてのビジュアル要素のレイアウトを計算するために使用されてスクリーンに描画されます。いくつかのケースでは、CPU の代わりに GPU を使用してスクリーンの一部を描画し、メインスレッドを解放してパフォーマンスを改善するために、コンテンツ自身をレイヤーに昇格し、コンポジットを行います。

+

レンダリングのステップは、スタイル、レイアウト、描画、そして合成で構成されます。パースのステップで作成された CSSOM と DOM のツリーはレンダーツリーの形式へと組み合わされ、すべてのビジュアル要素のレイアウトを計算するために使用されてスクリーンに描画されます。いくつかのケースでは、CPU の代わりに GPU を使用してスクリーンの一部を描画し、メインスレッドを解放してパフォーマンスを改善するために、コンテンツ自身をレイヤーに昇格し、合成を行います。

-

スタイル

+

スタイル

クリティカルレンダリングパスの 3 番目のステップは DOM と CSSOM をレンダーツリーの形式へと組み合わせることです。計算されたスタイルのツリー、あるいはレンダーツリー、の構築は DOM ツリーのルートからスタートし、目に見える (Visible) ノードをトラバースします。

@@ -171,45 +171,45 @@ translation_of: Web/Performance/How_browsers_work

それぞれの目に見えるノードには、CSSOM のルールが適用されます。レンダーツリーはすべての目に見えるノードをコンテンツと計算されたスタイルを合わせて保持します。すべての関連するスタイルと DOM 上の目に見えるノードをマッチングし、CSS カスケードに基づいて、それぞれのノードに対応する計算されたスタイルを決定します。

-

レイアウト

+

レイアウト

-

クリティカルレンダリングパスの 4 番目のステップは各ノードの平面状の位置を計算するためにレイアウト処理を実行することです。レイアウトはレンダーツリーに含まれるすべてのノードの幅と高さ、位置を決める処理です。さらにページ上のそれぞれオブジェクトのサイズと位置を決定します。リフローは、続いて発生するドキュメント全体、あるいはページの一部分のサイズと位置を決める処理です。

+

クリティカルレンダリングパスの 4 番目のステップは各ノードの平面状の位置を計算するためにレイアウト処理を実行することです。レイアウトはレンダーツリーに含まれるすべてのノードの幅と高さ、位置を決める処理です。さらにページ上のそれぞれオブジェクトのサイズと位置を決定します。再フローは、続いて発生するドキュメント全体、あるいはページの一部分のサイズと位置を決める処理です。

レンダーツリーが構築されるとすぐにレイアウトが始まります。レンダーツリーは計算されたスタイルを踏まえてどのノードが表示されるか (非表示であっても) 特定しますが、寸法や位置は特定しません。各オブジェクトの正確なサイズと位置を決めるために、ブラウザーがレンダーツリーのルートからトラバースを行います。

ウェブページ上では、ほとんどすべての要素はボックスです。異なるデバイス、異なるデスクトップの設定は、ビューポートのサイズの数が無制限に存在することを示しています。このフェーズにおいて、ビューポートのサイズを考慮して、ブラウザーはすべての異なるボックスのスクリーン上の寸法を決定します。ビューポートのサイズを基本として、レイアウトは一般的にボディからスタートし、すべてのボディの子孫をそれぞれの要素のボックスモデルプロパティに合わせてレイアウトし、画像のように寸法がわからない代替要素のためのプレースホルダースペースを作成します。

-

ノードのサイズとポジションが決められる最初のタイミングをレイアウトと呼びます。続いて発生するノードのサイズと位置の再計算をリフロー呼びます。私たちの例では、画像が返される前に最初のレイアウトが発生すると考えられます。画像のサイズを宣言していなかったため、画像のサイズがわかるとすぐにリフローが発生します。

+

ノードのサイズとポジションが決められる最初のタイミングをレイアウトと呼びます。続いて発生するノードのサイズと位置の再計算を再フロー呼びます。私たちの例では、画像が返される前に最初のレイアウトが発生すると考えられます。画像のサイズを宣言していなかったため、画像のサイズがわかるとすぐに再フローが発生します。

-

ペイント

+

描画

-

クリティカルレンダリングパスの最後のステップは個別のノードをスクリーンにペイントすることです。最初に発生するペイントを first meaningful paint と呼びます。ペイントまたはラスタライゼーションのフェーズにおいて、ブラウザーはレイアウトフェーズで計算されたそれぞれのボックスをスクリーン上の実際のピクセルに変換します。ペイントは、テキスト、色、ボーダー、シャドウ、ボタンや画像のような置換要素を含む、要素のすべての視覚的な部分をスクリーンに描くことを含みます。ブラウザーはこれを超高速で実行する必要があります。

+

クリティカルレンダリングパスの最後のステップは個別のノードをスクリーンに描画することです。最初に発生する描画を first meaningful paint と呼びます。描画またはラスタライズのフェーズにおいて、ブラウザーはレイアウトフェーズで計算されたそれぞれのボックスをスクリーン上の実際のピクセルに変換します。描画は、テキスト、色、境界、シャドウ、ボタンや画像のような置換要素を含む、要素のすべての視覚的な部分をスクリーンに描くことを含みます。ブラウザーはこれを超高速で実行する必要があります。

-

スムーズなスクロールとアニメーションを実現するために、スタイルの計算やリフロー、ペイントなどメインスレッドを占有するすべての処理は、16.67ms 未満で完了する必要があります。2048 x 1536 の解像度を持つ iPad は 3,145,000 を超えるピクセルを持っています。それら大量のピクセルは高速にペイントされなければいけません。2回目以降のペイントを最初のペイントより高速にするため、スクリーンへの描画は一般的に複数のレイヤーに分解されます。この場合にコンポジットが必要になります。

+

スムーズなスクロールとアニメーションを実現するために、スタイルの計算や再フロー、描画などメインスレッドを占有するすべての処理は、16.67ms 未満で完了する必要があります。2048 x 1536 の解像度を持つ iPad は 3,145,000 を超えるピクセルを持っています。それら大量のピクセルは高速に描画されなければいけません。2回目以降の描画を最初の描画より高速にするため、スクリーンへの描画は一般的に複数のレイヤーに分解されます。この場合に合成が必要になります。

-

ペイントはペイントツリー内の要素をレイヤーに分解します。コンテンツを GPU (CPU 上のメインスレッドの代わりになる) 上のレイヤーに昇格させることで、ペイントと再ペイントのパフォーマンスを向上します。<video><canvas>など、レイヤーを生成する特定のプロパティと要素があります。opacity、3D transformwill-change、その他いくつかの CSS プロパティを持つ要素も同様です。これらのノードは、その子孫が上記の理由でそれ自身のレイヤーを必要とするのでなければ、子孫と一緒に自身のレイヤー上に描画されます。

+

描画は描画ツリー内の要素をレイヤーに分解します。コンテンツを GPU (CPU 上のメインスレッドの代わりになる) 上のレイヤーに昇格させることで、描画と再描画のパフォーマンスを向上します。<video><canvas>など、レイヤーを生成する特定のプロパティと要素があります。opacity、3D transformwill-change、その他いくつかの CSS プロパティを持つ要素も同様です。これらのノードは、その子孫が上記の理由でそれ自身のレイヤーを必要とするのでなければ、子孫と一緒に自身のレイヤー上に描画されます。

レイヤーはパフォーマンスを改善しますが、メモリー管理の面ではコストのかかる処理です。そのため、ウェブのパフォーマンス最適化戦略の中で濫用するべきものではありません。

-

コンポジット

+

合成

-

ドキュメントのセクションが異なるレイヤーに描画されて重なり合う場合、コンテンツをスクリーン上に正しい順番で描画するためにコンポジットが必要になります。

+

ドキュメントのセクションが異なるレイヤーに描画されて重なり合う場合、コンテンツをスクリーン上に正しい順番で描画するために合成が必要になります。

-

ページがアセットの読み込みを続ける間もリフローは発生します (後ほど出てくる図を見てください)。リフローは再ペイントと再コンポジットを引き起こします。画像のサイズを指定していた場合リフローは必要ありません。再ペイントが必要なレイヤーのみが再ペイントされ、必要があればコンポジットが行われます。しかし、私たちのサンプルでは画像のサイズを指定しませんでした。画像がサーバーから取得されたとき、レンダリングプロセスはレイアウトステップまで戻り、そこから再開します。

+

ページがアセットの読み込みを続ける間も再フローは発生します (後ほど出てくる図を見てください)。再フローは再描画と再合成を引き起こします。画像のサイズを指定していた場合再フローは必要ありません。再描画が必要なレイヤーのみが再描画され、必要があれば合成が行われます。しかし、私たちのサンプルでは画像のサイズを指定しませんでした。画像がサーバーから取得されたとき、レンダリングプロセスはレイアウトステップまで戻り、そこから再開します。

-

インタラクティビティ

+

操作可能性

-

メインスレッドがページのペイントを完了したら「これで終わり」と思うかもしれません。しかし、必ずしもそうとは言えません。読み込み処理が、遅延された onload イベントの発火により実行される JavaScript を含む場合、メインスレッドがビジー状態となりスクロールやタッチ、その他のインタラクションができない場合があります。

+

メインスレッドがページの描画を完了したら「これで終わり」と思うかもしれません。しかし、必ずしもそうとは言えません。読み込み処理が、遅延された onload イベントの発行により実行される JavaScript を含む場合、メインスレッドがビジー状態となりスクロールやタッチ、その他の操作ができない場合があります。

-

{{glossary('Time to Interactive')}} (TTI) は、DNS ルックアップと SSL コネクション を始める最初のリクエストからページがインタラクティブになるまでどのくらい時間がかかったかを示す測定値です。インタラクティブであるとは、ページがユーザーのインタラクションに 50ms 以内に応答する {{glossary('First Contentful Paint')}} の後の時点を言います。メインスレッドがパース処理、コンパイル、JavaScript の実行に占有されている場合、ユーザーのインタラクションにタイムリーに (50ms より早く) 応答することができません。

+

{{glossary('Time to Interactive')}} (TTI) は、DNS ルックアップと SSL コネクション を始める最初のリクエストからページが操作可能になるまでどのくらい時間がかかったかを示す測定値です。操作可能であるとは、ページがユーザーの操作に 50ms 以内に応答する {{glossary('First Contentful Paint')}} の後の時点を言います。メインスレッドがパース処理、コンパイル、JavaScript の実行に占有されている場合、ユーザーの操作にタイムリーに (50ms より早く) 応答することができません。

以下の例では、画像の読み込みは高速かもしれませんが、anotherscript.js ファイルが 2MB あり、しかもユーザーのネットワークは低速です。このケースでは、ユーザーはページのコンテンツをすぐに見ることができるかもしれませんが、スクリプトがダウンロードされるまでスクロールを実行できない可能性があります。これは良いユーザー体験とは言えません。この WebPageTest の例からわかるように、メインスレッドを占有することは避けなければいけません。

-

The main thread is occupied by the downloading, parsing and execution of a  javascript file - over a fast connection

+

メインスレッドは javascript ファイルのダウンロード、解析、実行で占められています (高速接続時)。

この例では、DOM コンテンツの読み込みプロセスは 1.5 秒以上かかっており、メインスレッドがすべての時間を完全に占有され、クリックイベントや画面のタップに応答できなくなっています。

-

関連情報

+

関連情報