You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: WEB-INTEGRATION.md
+8-3Lines changed: 8 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -282,13 +282,15 @@ waiting on some I/O operation to progress or complete. We can further divide th
282
282
###### Objects responsible for one task
283
283
284
284
Asynchronous APIs that fire events as a result of either:
285
-
- some method/setter call, for which the event is fired either (a) on the object returned by the method (either directly or wrapped in a promise), or (b) if the instance is not a singleton on the object whose method was called on, would propagate the context;
285
+
- some method/setter call, for which the event is fired either (a) on an object created by the method, or (b) if the instance is not a singleton on the object whose method was called on, would propagate the context;
286
286
- creating a DOM object, attaching it to the DOM, or changing some attribute, for which the event is fired on that same DOM object.
287
287
288
288
This includes all the events that are conceptually similar to promise (e.g. `load`, except for the global page load), for which it's most important that the context is propagated. It excludes events dispatched on singletons, such as `window`/`document`/`document.fonts`, as these singletons do not represent a task but are simply a place where to listen for global events.
289
289
290
290
The context would be stored on this "holder object" when the task starts, and used to dispatch events that represent progress/completion of the task. It would be cleared when the task is known to be completed, since further events are known to not be fired anymore (unless the task is re-started, in which case it would capture a new context). Events "emulated" through `.dispatchEvent` would not use this context, as it's the _caller_ of the event-dispatching logic that is responsible for setting it up.
291
291
292
+
In case where an API has methods to start an action and then methods that can affect it while in-progress without cancelling and re-starting it (for example, calling `.pause()` on a video _may_ cause the browser to suspend loading it, to then restart when calling `.play()`), the AsyncContext that gets propagated is the one that was active when the action was originally started.
293
+
292
294
An example of an API where this is possible is `XMLHttpRequest`, which if implemented in JavaScript could look like this:
293
295
294
296
<details>
@@ -371,12 +373,15 @@ function listen() { // called after run()
371
373
}
372
374
```
373
375
374
-
When creating/updating/attaching these DOM objects (which happens synchronously), the browser will need to read the pointer to the AsyncContext map from the current agent, and store it on those objects. Note that all objects created/updated from a single mutation will reference the same AsyncContext. Chrome implements similar capturing for task attribution, and has not found any relevant performance degradation.
376
+
When creating/updating these DOM objects (which happens synchronously), the browser will need to read the pointer to the AsyncContext map from the current agent, and store it on those objects. Note that all objects created/updated from a single mutation will reference the same AsyncContext. Chrome implements similar capturing for task attribution, and has not found any relevant performance degradation.
375
377
376
378
Some DOM objects can represent multiple "actions" in parallel. For example, a `<link>` element might have it `href` value changed before that the `load` event for the first resource is fired. In this case the second loading process will start while the first one is still completing, thus the `AsyncContext` snapshot of both needs to be kept around.
377
379
378
380
In case of event propagation through the DOM (capturing and bubbling), all event handlers run in the context captured by the target element, as the event dispatching process would be to first set the appropriate context, and then run all the existing event machinery.
379
381
382
+
> [!NOTE]
383
+
> While this does not automatically cover _adoption_ of DOM nodes that causes resource loading, DOM-caused resource loading is one of the main tracing needs. This principle will need to be expanded to cover adoption other than creation/modification.
384
+
380
385
###### Events dispatched on separate objects
381
386
382
387
Some async APIs allow starting tasks that then will cause events on _other_ objects to be fired. Some examples are:
@@ -396,7 +401,7 @@ The usefulness of propagating the current trace/context in these cases varies a
396
401
397
402
1. APIs that dispatch events synchronously do not change the currently active async context, like all other synchronous APIs.
398
403
2. Events fired due to JS-external causes, such as user interaction, run the event handlers in an empty context.
399
-
3. Asynchronous APIs that fire events as a result of some method/setter call, for which the event is fired either (a) on the object returned by the method (either directly or wrapped in a promise), or (b) if the instance is not a singleton on the object whose method was called on, propagate the context.
404
+
3. Asynchronous APIs that fire events as a result of some method/setter call, for which the event is fired either (a) on the object created by the method, or (b) if the instance is not a singleton on the object whose method was called on, propagate the context.
400
405
4. Asynchronous APIs that dispatch events on separate objects do not propagate the context (and run the event handlers in an empty one), regardless of whether they are cross-thread or same-thread.
401
406
5. Some special error-reporting events (`ErrorEvent`, `PromiseRejectionEvent`, `SecurityPolicyViolationEvent`) fall under (3), but will have an extra property on the event object exposing the context of the code that caused the error.
0 commit comments