aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/performance/how_browsers_work/index.html
blob: 9483fed99b1e4b9370d74fb955eaaec97f0663e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
---
title: 'ページの生成: ブラウザーの動作の仕組み'
slug: Web/Performance/How_browsers_work
tags:
  - Browsers
  - Compositing
  - Critical rendering path
  - DNS Lookup
  - Navigation
  - Page load
  - Painting
  - SSL/TLS Handshake
  - TCP handshake
  - Web Performance
  - render
translation_of: Web/Performance/How_browsers_work
---
<p>ユーザーは、読み込みが速く、スムーズに操作できるコンテンツを、ウェブで体験することを求めています。したがって、<span class="seoSummary">開発者はこれらふたつの目標を達成するために努力しなければいけません。</span></p>

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

<h2 id="Overview">概要</h2>

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

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

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

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

<h2 id="Navigation">ナビゲーション</h2>

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

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

<h3 id="DNS_Lookup">DNS ルックアップ</h3>

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

<p>ブラウザーが DNS ルックアップをリクエストし、そのリクエストは最終的にネームサーバーによって処理され、ネームサーバーが IP アドレスを返します。この最初のリクエストの後、多くの場合その IP アドレスはしばらくの間キャッシュされ、ネームサーバーへ再接続する代わりにキャッシュから IP アドレスを取得することによって、後続するリクエストの速度を向上します。</p>

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

<p><img alt="携帯電話のリクエストは、まずセルタワーに送られ、次に電話会社の中央コンピューターに送られた後、インターネットに送信される" src="latency.jpg"></p>

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

<h3 id="TCP_Handshake">TCP ハンドシェイク</h3>

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

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

<h3 id="TLS_Negotiation">TLS ネゴシエーション</h3>

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

<p><img alt="DNS ルックアップ、TCP ハンドシェイク、そして TLS ハンドシェイクの 5 つのステップ (clienthello、serverhello、証明書、clientkey、サーバーとクライアントの両方の完了)。" src="ssl.jpg"></p>

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

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

<h2 id="Response">レスポンス</h2>

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

<pre class="brush: html">&lt;!doctype HTML&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;meta charset="UTF-8"/&gt;
  &lt;title&gt;My simple page&lt;/title&gt;
  &lt;link rel="stylesheet" src="styles.css"/&gt;
  &lt;script src="myscript.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1 class="heading"&gt;My Page&lt;/h1&gt;
  &lt;p&gt;A paragraph with a &lt;a href="https://example.com/about"&gt;link&lt;/a&gt;&lt;/p&gt;
  &lt;div&gt;
    &lt;img src="myimage.jpg" alt="image description"/&gt;
  &lt;/div&gt;
  &lt;script src="anotherscript.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>

<p>この最初のリクエストへのレスポンスは、受信データの最初のバイト (First Byte) を含んでいます。{{glossary('Time to First Byte')}} (TTFB) は、ユーザーがリクエストを実行した時点から—たとえば、リンクをクリックした時点から— HTML の最初のパケットを受信するまでの時間を表します。コンテンツの最初のかたまり (Chunk) は一般的に 14kB のデータです。</p>

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

<h3 id="TCP_Slow_Start_14kb_rule">TCP スロースタート / 14kB ルール</h3>

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

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

<p><img alt="TCP スロースタート" src="congestioncontrol.jpg"></p>

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

<h3 id="Congestion_control">輻輳制御</h3>

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

<h2 id="Parsing">パース処理</h2>

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

<p>DOM はブラウザー向けのマークアップの内部的な表現です。DOM は外部に公開されており、JavaScript の様々な API を通じて操作できます。</p>

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

<h3 id="Building_the_DOM_tree">DOM ツリーの構築</h3>

<p><a href="/ja/docs/Web/Performance/Critical_rendering_path">クリティカルレンダリングパス</a>の 5 つのステップを説明します。</p>

<p>最初のステップは HTML のマークアップを処理し、DOM ツリーを構築することです。HTML のパース処理は、<a href="/ja/docs/Web/API/DOMTokenList">トークン化</a>とツリーの構築に分かれます。HTML のトークンは開始タグと終了タグ、属性の名前と値を含みます。ドキュメントが正しく構成されていればパース処理は単純で、速度も速くなります。パーサーはトークン化された入力情報をドキュメントツリーを構成するドキュメントに変換します。</p>

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

<p><img alt="サンプルコードの DOM ツリーで、テキストノードを含むすべてのノードが表示されています。" src="dom.gif"></p>

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

<h3 id="Preload_scanner">プリロードスキャナー</h3>

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

<pre class="brush:html">&lt;link rel="stylesheet" src="styles.css"/&gt;
&lt;script src="myscript.js" <strong>async</strong>&gt;&lt;/script&gt;
&lt;img src="myimage.jpg" alt="image description"/&gt;
&lt;script src="anotherscript.js" <strong>async</strong>&gt;&lt;/script&gt;
</pre>

<p>この例では、メインスレッドが HTML と CSS をパースしている間に、プリロードスキャナーがスクリプトと画像を探索し、それらのダウンロードを開始します。もし JavaScript の実行順序が重要でないなら、スクリプトがプロセスをブロックしないように <code>async</code> 属性または <code>defer</code> 属性を追加しましょう。</p>

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

<h3 id="Building_the_CSSOM">CSSOM の構築</h3>

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

<p>HTML の場合と同様に、ブラウザーは受信した CSS のルールをブラウザーが実行可能な形式に変換しなければいけません。そのために、ブラウザーは HTML をオブジェクトに変換する場合と同じプロセスを CSS に対しても実行します。</p>

<p>CSSOM ツリーはユーザーエージェントのスタイルシートから取得したスタイルを含みます。ブラウザーは、ノードに対して適用される最も一般的なルールからスタートして、より特定されたルールを再帰的に適用し、最終的なスタイルを計算します。つまり、プロパティの値をカスケードします。</p>

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

<h3 id="Other_Processes">その他の処理</h3>

<h4 id="JavaScript_Compilation">JavaScript のコンパイル</h4>

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

<h4 id="Building_the_Accessibility_Tree">アクセシビリティツリーの構築</h4>

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

<p>AOM が構築されるまで、<a href="/ja/docs/Web/Accessibility/ARIA/ARIA_Screen_Reader_Implementors_Guide">スクリーンリーダー</a>でコンテンツにアクセスできません。</p>

<h2 id="Render">レンダリング</h2>

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

<h3 id="Style">スタイル</h3>

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

<p>ユーザーエージェントのスタイルシートにある <code>&lt;head&gt;</code> のような表示されることないタグとその子要素、<code>script { display: none; }</code> のように <code>display: none</code> を指定されたすべてのノード、はレンダリングの結果に影響しないためレンダーツリーには含まれません。<code>visibility: hidden</code> が適用されたノードは、スペースを確保するためレンダーツリーに含まれます。上記のサンプルコード内の <code>script</code> ノードは、ユーザーエージェントのデフォルトを上書きするディレクティブが指定されていないためレンダーツリーに含まれません。</p>

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

<h3 id="Layout">レイアウト</h3>

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

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

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

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

<h3 id="Paint">描画</h3>

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

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

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

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

<h3 id="Compositing">合成</h3>

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

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

<h2 id="Interactivity">操作可能性</h2>

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

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

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

<p><img alt="メインスレッドは javascript ファイルのダウンロード、解析、実行で占められています (高速接続時)。" src="visa_network.png"></p>

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

<h2 id="See_Also">関連情報</h2>

<ul>
 <li><a href="/ja/docs/Web/Performance">ウェブパフォーマンス</a></li>
</ul>