/
721.txt
369 lines (314 loc) · 18.5 KB
/
721.txt
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
[2] [DFN[[[stops parsing]]]] は、[[構文解析]]が完了して[[文書]]の準備が完了した際に実行される[[手順]]
([[仕様書]]上の[[アルゴリズム]]) です。
[[文書]]を構文解析モードから通常モードへと切り替える働きがあります。
[CODE(DOMe)@en[[[DOMContentLoaded]]]] や [CODE(DOMe)@en[[[load]]]]
の[[イベント]]は、この[[手順]]から[[発火]]されます。
* 仕様書
[REFS[
- [69] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-05-06 10:42:35 +09:00]] 版) <https://html.spec.whatwg.org/#current-document-readiness>
- [1] '''[CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-05-06 10:42:35 +09:00]] 版) <https://html.spec.whatwg.org/#stop-parsing>'''
- [66] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-05-06 10:42:35 +09:00]] 版) <https://html.spec.whatwg.org/#delaying-load-events-mode>
- [78] [CITE@en[Resource Hints]] ([TIME[2016-05-21 01:13:13 +09:00]]) <https://w3c.github.io/resource-hints/#h-load-and-error-events>
]REFS]
* 文脈
[43] 次の場面で呼び出されます。
[FIG(middle list)[
- [[HTML構文解析器]]
- [[XML構文解析器]]
- [[XSLT]] による変換完了(成功)時
- [[媒体文書]]の読み込み
- [[プラグイン文書]]の読み込み
- [[非文書表示]]
]FIG]
;; [46] つまり [[navigate]] の結果[[閲覧文脈]]の[[文書]]が更新された時には必ず実行されます。
[45] [[navigate]] は、
[FIG(list)[
- [[セッション履歴を新しいページで更新]]
- [[素片識別子へのスクロール]]
]FIG]
... を (必要なら) [[stops parsing]] より前に行っておく必要があります ([[navigate]] 参照)。
これらはどちらも[[ネットワーク処理タスク源]]の[[タスク]]なので、
[[fetch]] が [[process response end-of-file]] で [[stops parsing]]
を呼び出すことになる[[タスク]]を[[タスクキューに追加]]するよりも前の段階でこれらの[[タスク]]を追加しておく必要があることになります。
;; 通常はそれよりもかなり前の段階で行われます。[[レンダリングの開始]]も参照。
@@
[14] [[自動補完]]、[[パスワードマネージャー]]への保存
* 処理
[4] [[構文解析器]][VAR[構文解析器]]の [[stops parsing]] は、まず次のようにしなければ[['''なりません''']]。
[FIG(steps)[
= [5] [VAR[構文解析器]]の[F[[[文書]]]]の[F[[[現在文書準備度]]]]を、
[CODE[[[interactive]]]] に設定します [SRC[>>1]]。
= [72] [[単純イベントを発火]]します。 [SRC[>>69]]
[FIG(list members)[
[FIGCAPTION[
[[単純イベント]]
]FIGCAPTION]
:[[イベント型]]:[CODE(DOMe)@en[[[readystatechange]]]]
:[[対象]]: [VAR[構文解析器]]の[F[[[文書]]]]
]FIG]
= [6] [VAR[構文解析器]]の[F[[[挿入点]]]]を、 null に設定します [SRC[>>1]]。
= [7] [VAR[構文解析器]]の[F[[[開いている要素のスタック]]]]の[[節点]]をすべて [[pop]] します [SRC[>>1]]。
= [10] [VAR[構文解析器]]について構文解析終了後のスクリプト実行の処理
([CODE(HTMLe)@en[[[script]]]] 参照。) を実行します。[VAR[続きの処理]]は >>15 とします。 [SRC[>>1]]
=- [76] これは、 [CODE(HTMLa)@en[[[defer]]]] [[属性]](相当)が適用される
[CODE(HTMLe)@en[[[script]]]] [[要素]]の実行です。
=- [12] [VAR[続きの処理]]が同期的に呼び出されることもあれば、
別の[[タスク]]となることもあります。
]FIG]
[15] 更なる処理が[VAR[構文解析器]]について呼び出されたら、
次のようにしなければ[['''なりません''']] [SRC[>>1]]。
[FIG(steps)[
= [13] 新しい[[タスク]]を[[タスクキューに追加]]します。
[FIG(list members)[
[FIGCAPTION[
[[タスク]]
]FIGCAPTION]
:[F[[[タスク源]]]]:[[DOM操作タスク源]]
:[F[処理]]:
[FIG(steps)[
= [16] [[単純イベントを発火]]します。
[FIG(list members)[
[FIGCAPTION[
[[単純イベント]]
]FIGCAPTION]
:[[イベント型]]:[CODE(DOMe)@en[[[DOMContentLoaded]]]]
:[[対象]]: [VAR[構文解析器]]の[F[[[文書]]]]
]FIG]
]FIG]
]FIG]
]FIG]
[17] 現在の[[タスク]]はこれで終了します。更に、
[FIG(list)[
- [18] [[set of scripts that will execute as soon as possible]] が空になる
- [19] [[the list of scripts that will execute in order as soon as possible]] が空になる
- [20] [[delay the load event]] するものがなくなる
]FIG]
... の''すべて''の条件が満たされたら、現在の[[タスク]]と同じ[[タスク源]]の新たな[[タスク]]を[[タスクキューに追加]]しなければ[['''なりません''']] [SRC[>>1]]。
;; [34] つまり、残りの[[スクリプト]]の実行完了と埋め込まれた[[資源]]の読み込み完了を待ちます。
[21] 新たな[[タスク]]は、次のようにしなければ[['''なりません''']] [SRC[>>1]]。
[FIG(steps)[
= [22] [[タスク]]を[[タスクキューに追加]]します。
[FIG(list members)[
[FIGCAPTION[
[[タスク]]
]FIGCAPTION]
:[[タスク源]]:[[DOM操作タスク源]]
:処理:
[FIG(steps)[
= [23] [[現在文書準備度]]を、 [CODE[[[complete]]]] に設定します。
= [71] [[単純イベントを発火]]します。 [SRC[>>69]]
[FIG(list members)[
[FIGCAPTION[
[[単純イベント]]
]FIGCAPTION]
:[[イベント型]]:[CODE(DOMe)@en[[[readystatechange]]]]
:[[対象]]:[[文書]]
]FIG]
]FIG]
]FIG]
= [24] [[文書]]が[[閲覧文脈]]中にあるなら、[[単純イベントを発火]]します。
[FIG(list members)[
[FIGCAPTION[
[[単純イベント]]
]FIGCAPTION]
:[[イベント型]]:[CODE(DOMe)@en[[[load]]]]
:[[対象]]:[[文書]]の [CODE(DOMi)@en[[[Window]]]]
:[[対象上書き]]:[[文書]]
]FIG]
= [25] [[文書]]が[[閲覧文脈]]中にあるなら、[[タスク]]を[[タスクキューに追加]]します。
[FIG(list members)[
[FIGCAPTION[
[[タスク]]
]FIGCAPTION]
:[[タスク源]]:[[DOM操作タスク源]]
:処理:
[FIG(steps)[
= [26] [[文書]]の [[page showing flag]] が[[偽]]なら、
== [27] [[文書]]の [[page showing flag]] を、[[真]]に設定します。
== [28] [[イベントを発火]]します。
[FIG(list members)[
[FIGCAPTION[
[[イベント]]
]FIGCAPTION]
:[[イベントインターフェイス]]:[CODE(DOMi)@en[[[PageTransitionEvent]]]]
:[[イベント型]]:[CODE(DOMe)@en[[[pageshow]]]]
:[[対象]]:[[文書]]の [CODE(DOMi)@en[[[Window]]]]
:[[対象上書き]]:[[文書]]
:[[trusted]]:[[真]]
:[[bubbles]]:[[偽]]
:[[取消可能]]:[[偽]]
:[CODE(DOMa)@en[[[persisted]]]]:[[偽]]
:[[既定動作]]:なし
]FIG]
]FIG]
]FIG]
= [29] [[文書]]の [[pending application cache download process tasks]] に[[タスク]]があれば、
そのままの順序で、[[ネットワーク処理タスク源]]で[[タスクキューに追加]]します。リストは空にします。
= [30] [[文書]]の [[print when loaded flag]] が設定されていれば、
[[printing steps]] を実行します。
= [31] [[文書]]を、 [[ready for post-load tasks]] とします。
= [25] [[タスク]]を[[タスクキューに追加]]します。
[FIG(list members)[
[FIGCAPTION[
[[タスク]]
]FIGCAPTION]
:[[タスク源]]:[[DOM操作タスク源]]
:処理:
[FIG(steps)[
= [32] [[文書]]の [[completely loaded]] を設定します。
]FIG]
]FIG]
]FIG]
;; [60] [[page showing flag]] が[[真]]の状態でここに到達することがあるのかどうか謎です。
;; [42] [[printing steps]] は[[イベントループ]]の[[一時停止]]を呼び出すことがあります。
[[イベント]]を同期的に[[発火]]することもあります。
;; [11] [[HTML Standard]] は [[stops parsing]] を[[イベントループのスピン]]を使って記述していますが、
次の性質から、
[[stop parsing]] 中 (構文解析終了後のスクリプト実行の処理 >>10 を含む。)
の[[スピン]]は、[[スピン]]を使わないで説明できます。
[FIG(list)[
- [[スピン]]を使った場合と使わないここで示した説明の違いは、
[[大域スクリプト片付けジョブ]]と[[マイクロタスク]]の実行のタイミング[DEL[と、[[ストレージミューテックスの解放]]]]のタイミングです。
- [[構文解析器]]以外の[[タスク]]等がこれらを追加していた場合には、
[[イベントループ]]等により [[stops parsing]] の[[タスク]]より前に実行されているはずです。
- [[スクリプト]]がこれらを追加していた場合には、
[[コールバックを走らせた後の片付け]]により[[スクリプト]]実行直後に実行されているはずです。[DEL[[[イベントループ]]が[[ストレージミューテックス]]を取得していた場合も、ここで解放されているはずです。]]
- [DEL[[[構文解析器]]が [CODE(HTML)@en[<[[meta]] [[http-equiv]]=[[Set-Cookie]]>]] を処理する場合、[[ストレージミューテックス]]を取得した状態になります。[[スピン]]の場合と[[スピン]]を使わない説明とでは、解放のタイミングが変わってきます。ただし実際の [[Webブラウザー]]は[[ストレージミューテックス]]を使っていません。使っていたとしても、[[ストレージミューテックス]]を[[イベントループ]]が所有していることにより動作が違うことを観測するのは[[著者]]にとっても[[利用者]]にとっても困難と思われます。]]
- 残るのは、[[構文解析器]]の [[DOM]] 操作により[[マイクロタスク]]が追加されていた場合のみです。
- [[スピン]]を使わない説明の場合、現在の[[タスク]]が停止され[[イベントループ]]に戻ると、
次に[[イベントループ]]によって[[マイクロタスク]]が実行されることになります。
これは結局[[スピン]]の場合と同じです。
]FIG]
[35] [[閲覧文脈]]外にある[[文書]] ([[XHR]] などの[[文書]]や、 [[Webブラウザー]]以外の[[構文解析器]]の[[文書]]) の場合は、
[[スクリプト]]や埋め込み資源がなく、 [[stop parsing]] の完了後まで[[イベントリスナー]]を登録することもできませんから、次の通り簡略化できます。
[FIG(steps)[
= [36] [[開いている要素のスタック]]を空にします。
= [37] (本[[タスク]]を終えて新しい[[タスク]]で続きを実行します。)
= [38] [[現在文書準備度]]を [CODE[[[complete]]]] に設定します。
]FIG]
;; [39] 仕様通り解釈すると >>37 の[[スピン]]は必ず発生することになりますが、
実際には必要ないはずです。
* 副作用
[48] [[stops parsing]] は[[構文解析器]]の処理を終える作業であり、
[[構文解析器]]の動作中と動作後で異なる動きをする処理の分岐フラグが立てられるタイミングです。
[47] [[stops parsing]] 開始段階:
[FIG(list)[
- [49] [CODE(JS)@en[[[document.write]]]]/[CODE(JS)@en[[[document.writeln]]]]
は以後 [CODE(JS)@en[[[document.open]]]] を伴うようになります。
- [9] [[開いている要素のスタック]]から[[節点]]を [[pop]] すると、
副作用で何らかの動作が行われることがあります。[[開いている要素のスタック]]を参照。
]FIG]
[8] [CODE(DOMe)@en[[[DOMContentLoaded]]]] 段階:
[FIG(list)[
- [33] [[Webブラウザー]]によっては、 [CODE(DOMe)@en[[[DOMContentLoaded]]]]
の時点で[[ブラウザー拡張]]の[[内容スクリプト]]を実行することがあります。
([CODE(DOMe)@en[[[DOMContentLoaded]]]] も参照。)
- [70] [[Webブラウザー]]によっては、 [CODE(DOMe)@en[[[DOMContentLoaded]]]]
より後の都合の良い時点で[[ブラウザー拡張]]の[[内容スクリプト]]を実行することがあります。
]FIG]
[57] [CODE(DOMe)@en[[[load]]]] 段階:
[FIG(list)[
- [58] [[Webブラウザー]]によっては、 [CODE(DOMe)@en[[[load]]]]
の時点で[[ブラウザー拡張]]の[[内容スクリプト]]を実行することがあります。
]FIG]
[50] [DFN[[[ready for post-load tasks]]]] ([[stops parsing]] 自体の実行完了):
[FIG(list)[
- [52] [[閲覧文脈包含子]]たる [CODE(HTMLe)@en[[[iframe]]]]/[CODE(HTMLe)@en[[[object]]]]/[CODE(HTMLe)@en[[[embed]]]]/[CODE(HTMLe)@en[[[frame]]]] の [[delay the load event]] が終わります。
- [40] [[queue a post-load task]] ([[AppCache]] の処理の実行) が遅延されていたのが解除されます。
- [53] [CODE(JS)@en[[[window.print]]]] が遅延されていたのが解除されます。
- [41] 以後の [CODE(JS)@en[[[document.open]]]] が新しいソースコードを使うものだとみなされるようになります。
]FIG]
[51] [DFN[[[completely loaded]]]] ([[stops parsing]] により追加された[[DOM操作タスク源]]の[[タスク]]の実行完了):
[FIG(list)[
- [54] [CODE(HTTP)@en[[[Refresh]]]] の計測開始が遅延されていたのが解除されます。
- [55] 以後 [CODE(HTMLe)@en[[[iframe]]]]/[CODE(HTMLe)@en[[[frame]]]]、[[フォームの提出]]、[CODE(DOMi)@en[[[Location]]]]
の [[navigate]] で暗黙裡に[[置換有効]]とされなくなります。
- [56] [[閲覧文脈包含子]]たる [CODE(HTMLe)@en[[[iframe]]]]/[CODE(HTMLe)@en[[[frame]]]] [[要素]]で
[CODE(DOMe)@en[[[load]]]] [[イベント]]が[[発火]]されることがあります。
- [73] [[共有ワーカー]]を [[permissible worker]] とみなすかどうかの条件に影響します。
]FIG]
;; [74] [[permissible worker]] の条件は「complete loaded」となっており、
[[completely loaded]] と同じなのかは謎です。
[77] [CODE(HTMLe)@en[embed]] [[要素]]が [[SVG]] を埋め込む場合の処理で
「資源を完全に読み込んだ」タイミングを参照しており、 [[completely loaded]]
の意味と思われます。
[44] 更に「[[活性構文解析器]]」が [[stops parsing]] されていないこと(など)を定義としています。
[[stops parsing]] のどの段階まで完了したことを指すのかは不明瞭です。
[[活性構文解析器]]が参照されるのは [CODE(JS)@en[[[document.open]]]]
と [[abort a document]] で、前者はどの段階と解釈しても結果は変わりません。
後者は [[bfcache]] に影響します。 [[completely loaded]] と解釈するのが自然でしょうか。
[75] [[busy indicator]] も参照。
* [CODE(DOMe)@en[load]] イベントの遅延
[61] [CODE(DOMe)@en[[[load]]]] [[イベント]]は、埋め込み[[資源]]などの読み込みが終わってから[[発火]]されます。
[62] 仕様書上はこれは [DFN[[[delays the load event]]]] [SRC[>>1]] として記述されています。
各操作がいつからいつまで [[delay the load event]] するかが規定されており、
[[delay the load event]] するものがなくなった時、 [CODE(DOMe)@en[[[load]]]]
が[[発火]]できるようになります。 [[delay the load event]] は[[文書]]ごとの状態です。
[63] 次のものがあります。
[FIG(table)[
:element:[[要素]]
:start:遅延開始
:end:遅延終了
:element:[CODE(HTMLe)@en[[[link]]]] [SRC[[[HTML Standard]]]]
:start:[[obtain the resource]] の開始 (>>79 も参照)
:end:当該[[資源]]とその [[critical subresource]] の処理の完了
:element:[CODE(XML)@en[[[xml-stylesheet]]]]
:start:処理開始
:end:処理完了
:element:[CODE(HTMLe)@en[[[style]]]] [SRC[[[HTML Standard]]]],
[[SVG]] [CODE(XMLe)@en[[[style]]]]
:start:[[critical subresource]] の処理の開始
:end:[[critical subresource]] の処理の完了
:element:[CODE(HTMLe)@en[[[script]]]] [SRC[[[HTML Standard]]]],
[[SVG]] [CODE(XMLe)@en[[[script]]]]
:start:[[fetch]] 開始
:end: [[スクリプトの準備完了]]
:element:[CODE(HTMLe)@en[[[img]]]] [SRC[[[HTML Standard]]]]
:start:[[fetch]] 開始
:end:[[process response end-of-file]] [[タスク]]実行
:element:[CODE(HTML)@en[[[<input type=image>]]]] [SRC[[[HTML Standard]]]]
:start:[[fetch]] 開始
:end:[[process response end-of-file]] [[タスク]]実行
:element:[CODE(HTMLe)@en[[[iframe]]]] [SRC[[[HTML Standard]]]],
[CODE(HTMLe)@en[[[frame]]]] [SRC[[[HTML Standard]]]],
[CODE(HTMLe)@en[[[embed]]]] [SRC[[[HTML Standard]]]],
[CODE(HTMLe)@en[[[object]]]] [SRC[[[HTML Standard]]]]
:start: >>64 のいずれかが発生した時:
:end: >>64 を''すべて''満たさなくなった時
:element:[CODE(HTMLe)@en[[[embed]]]] [SRC[[[HTML Standard]]]]
:start:[[fetch]] 開始
:end:完了
:element:[CODE(HTMLe)@en[[[object]]]] [SRC[[[HTML Standard]]]]
:start:[[fetch]] 開始
:end:処理[[タスク]]完了
:element:[CODE(HTMLe)@en[[[object]]]] [SRC[[[HTML Standard]]]]
:start:処理[[タスク]]を追加
:end:[[process response end-of-file]] [[タスク]]実行
:element:[CODE(HTMLe)@en[[[video]]]] [CODE(HTMLa)@en[[[poster]]]] [SRC[[[HTML Standard]]]]
:start:[[fetch]] 開始
:end:処理[[タスク]]完了
:element:[[媒体要素]] [SRC[[[HTML Standard]]]]
:start:[[delaying-the-load-event flag]] が[[真]]に
:end:[[delaying-the-load-event flag]] が[[偽]]に
]FIG]
[64] [[入れ子閲覧文脈]]は、次の条件が満たされるとき、 [[delay the load event]]
します。
[FIG(list)[
- [[入れ子閲覧文脈]]の[[活性文書]]が [[ready for post-load tasks]] で''ない''
- [[入れ子閲覧文脈]]の[[活性文書]]が [[delay the load event]] 中
- [[入れ子閲覧文脈]]が [[delaying [CODE(DOMe)@en[load]] events mode]]
]FIG]
[65] [[閲覧文脈]]の [DFN[[[delaying [CODE(DOMe)@en[load]] events mode]]]] [SRC[>>66]]
は、 [[navigate]] 中に設定され、 [[navigate]] が終わるときに除去されるフラグです。
;; [67] [[文書]]の [[delay the load event]] フラグに対して、 [[navigate]]
では[[文書]]が変化するため、こちらのフラグが使われるようです。
[68] [[入れ子閲覧文脈]]内の[[文書]]の場合、自身の [CODE(DOMe)@en[[[load]]]]
[[イベント]]が[[発火]]された後でも、[[親閲覧文脈]]側の[[文書]]の
[CODE(DOMe)@en[[[load]]]] [[イベント]]を遅延させる可能性がなお残ります。
[79] [CODE(HTML)@en[preconnect]], [CODE(HTML)@en[prefetch]], [CODE(HTML)@en[prerender]]
は遅延させません [SRC[>>78]]。 [CODE(HTML)@en[dns-prefetch]] も対象外です。
* 歴史
[59] [CODE(DOMe)@en[[[load]]]]、[CODE(DOMe)@en[[[DOMContentLoaded]]]]、
[CODE(DOMe)@en[[[pageshow]]]] も参照。
* 関連
[3] [[stops parsing]] のかわりに [[abort a parser]] が実行される場合もあります。