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
Apply feedback and refine Delayed Messages API explainer
- Updated problem description to clarify causes of `postMessage` delays and challenges in identifying root causes.
- Expanded explanation of deserialization timing inconsistencies across browsers.
- Refined summary of problems to emphasize the need for a dedicated API for diagnosing `postMessage` delays.
- Improved description of `PerformanceExecutionContextInfo.name` to clarify optionality for workers and windows/iframes.
- Removed "It adds boilerplate code and maintenance overhead" in manual instrumentation section.
- Added missing reference to the Event Timing API in the references section.
Copy file name to clipboardExpand all lines: DelayedMessages/explainer.md
+10-12Lines changed: 10 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ Web applications frequently use `postMessage` to send messages across different
8
8
9
9
Such delays can degrade user experience by making applications feel unresponsive. Identifying the root cause of these delays—whether it's a busy thread, a congested message queue, or the overhead of preparing message data—is currently challenging for web developers.
10
10
11
-
The Delayed Messages API allows web developers to identify congested browser contexts or workers and provide details on the end-to-end timing of `postMessage` events, as well as their related blocking tasks. These metrics help identify the causes of delays in `postMessage`handling and in improving the performance of web applications.
11
+
The Delayed Messages API allows web developers to identify congested browser contexts or workers and provide details on the end-to-end timing of `postMessage` events, as well as their related blocking tasks. These metrics help identify the causes of `postMessage`delays and improve application performance.
12
12
13
13
# Goals
14
14
@@ -26,15 +26,15 @@ This API does not aim to monitor or provide diagnostics for the following types
26
26
27
27
# Problems
28
28
29
-
When a developer sends a message using `postMessage` to a web worker or an iframe, they expect it to be processed on the target context in a timely manner. However, `postMessage` can experience significant delays, making it difficult to pinpoint the root cause. These delays might result from synchronous JavaScript executions blocking the main thread or worker thread, an excessive number of messages being sent too quickly, or significant time spent processing the data being transferred.
29
+
While developers expect messages sent via `postMessage` to web workers or iframes to be processed promptly, these tasks typically receive default priority in the browser's task scheduler(e.g. Chromium). As a result, `postMessage`communication can experience noticeable delays due to lower prioritization compared to user-visible tasks, often compounded by synchronous JavaScript blocking the target thread, a flood of messages overwhelming the message queue, or significant time spent processing the data being transferred, making the root cause challenging to pinpoint.
30
30
31
31
These problems can be broadly categorized into three areas:
32
32
33
33
1.**Thread being occupied:** The receiving thread is busy executing long-running tasks.
34
34
2.**Message queue becoming congested:** Too many messages are enqueued faster than they can be processed.
35
35
3.**Serialization/deserialization processes taking significant time:** The data being sent is large or complex, leading to overhead.
36
36
37
-
This section will analyze each area with examples. All examples involve web workers, but similar situations can also occur between the main window and iframes, or between different windows.
37
+
The following sections will analyze each area with examples. All examples involve web workers, but similar situations can also occur between the main window and iframes, or between different windows.
38
38
39
39
## Case 1: Thread Being Occupied
40
40
@@ -146,7 +146,7 @@ Manually instrumenting code with `performance.now()` and `event.timeStamp` can h
146
146
147
147
Even without individual long-running tasks, a high volume of messages sent in a short period can overwhelm the receiving context. The message queue can grow, leading to congestion and delays for all subsequent messages, including potentially urgent ones.
148
148
149
-
The following example codes demonstrates this situation, where multiple `deleteMail` tasks congest the message queue before an urgent `readMail` task.
149
+
The following example code demonstrates this situation, where multiple `deleteMail` tasks congest the message queue before an urgent `readMail` task.
150
150
151
151
[Link to live example](https://joone.github.io/web/explainers/delayed_messages/congested/)
152
152
@@ -297,7 +297,7 @@ While delays in background tasks like `deleteMail` might be acceptable, delays i
297
297
298
298
When data is sent using `postMessage`, it undergoes serialization by the sender and deserialization by the receiver. For large or complex JavaScript objects (e.g., a large JSON payload or a deeply nested object), these processes can consume considerable time, blocking the respective threads.
299
299
300
-
The following example code demonstrate the delay introduced by serializing/deserializing a large JSON object during postMessage.
300
+
The following example code demonstrate the delay introduced by serializing/deserializing a large JSON object during `postMessage`.
301
301
302
302
[Link to live demo](https://joone.github.io/web/explainers/delayed_messages/serialization/)
303
303
@@ -400,13 +400,11 @@ onmessage = (event) => {
400
400
```
401
401
As shown, serialization on the main thread (approx. 130.30 ms) occurs synchronously during the `postMessage` call, blocking other main thread work. Similarly, deserialization on the worker thread (approx. 114.30 ms) is a significant operation that blocks the worker's event loop during message processing, delaying the execution of the `onmessage` handler and any subsequent tasks.
402
402
403
-
In this example, the worker log `message queue wait time + etc: 130.40 ms` indicates the time elapsed from when the main thread initiated the `postMessage` (including its ~130.30 ms serialization block) to when the worker’s `onmessage` handler began execution. This suggests that the message queue wait time is nearly zero, and the delay is primarily caused by serialization on the sender side. However, when the event loop is also busy with other long tasks, it becomes difficult to distinguish these individual sources of delay (serialization, actual queueing, deserialization, and task execution) from other task delays without manual instrumentation.
404
-
405
-
This API proposes to expose these timings (`serialization`, `deserialization`, `blockedDuration`) explicitly, simplifying the diagnosis of such delays.
403
+
In this example, the worker log `message queue wait time + etc: 130.40 ms` indicates the time elapsed from when the main thread initiated the `postMessage` (including its ~130.30 ms serialization block) to when the worker’s `onmessage` handler began execution. This suggests that the message queue wait time is nearly zero, and the delay is primarily caused by serialization on the sender side. However, the timing of deserialization, which the [specification](https://html.spec.whatwg.org/multipage/web-messaging.html#dom-window-postmessage-options-dev) suggests should occur before the message event, can vary across browsers. For example, browsers like Chromium, may delay this process until the message data is actually accessed for the first time. This inconsistency, combined with a busy event loop that makes it difficult to distinguish serialization, actual queueing, deserialization, and task execution delays even with manual instrumentation, further underscores the need for an API to expose this particular timing information.
406
404
407
405
### Summary of Problems
408
406
409
-
Existing performance tools can help detect that messages are delayed, but pinpointing the *exact cause* is difficult. The delay could be due to serialization/deserialization, event handling logic, general browser overhead, or time spent in microtasks. Measuring message queue wait time accurately is also challenging. A dedicated API is needed to accurately measure, attribute, and identify sources of `postMessage` delays, simplifying diagnosis and optimization.
407
+
Message delays frequently occur and can degrade user experience. While existing tools can detect delays, pinpointing the exact cause is difficult. Delays often stem from the receiver's thread being busy with long tasks, message queue congestion, or serialization/deserialization overhead. Accurately measuring internal message queue wait time is especially challenging with manual instrumentation. A dedicated API is needed to precisely measure, attribute, and identify these specific sources of delay.
410
408
411
409
# Proposal: Introducing the Delayed Messages API
412
410
@@ -559,7 +557,7 @@ Returns a unique identifier for the execution context (e.g., a string or an inte
559
557
560
558
#### `PerformanceExecutionContextInfo.name`
561
559
562
-
Returns the name of the execution context. For workers, this is the name provided during instantiation (e.g., `new Worker("worker.js", { name: "MyWorker" })`). For windows or iframes, it might be empty or derived from `window.name`.
560
+
Returns the name of the execution context. For workers, this is the name provided during instantiation (e.g., `new Worker("worker.js", { name: "MyWorker" })`). It might be empty, as the name is optional. For windows or iframes, it might be empty or derived from `window.name`.
## Examples of a `delayed-message` Performance Entry
600
598
601
-
The following JSON shows example performance entries for the delayed messages identified in **Case 1: Thread Being Occupied**. This API automatically detects and reports these delays without requiring manual `performance.now()` tracking.
599
+
The following JSON shows sample performance entries for the delayed messages identified in **Case 1: Thread Being Occupied**. This API automatically detects and reports these delays without requiring manual `performance.now()` tracking.
602
600
603
601
By examining `blockedDuration` and the handler execution time (`processingEnd - processingStart`), developers can diagnose the cause:
604
602
@@ -724,7 +722,6 @@ Developers can attempt to wrap `postMessage` calls and `onmessage` handlers with
724
722
725
723
* It's challenging to intercept all messages, especially those from third-party libraries.
726
724
* Accurately measuring internal browser operations like serialization, deserialization, and precise queue waiting time is not feasible from JavaScript.
727
-
* It adds boilerplate code and maintenance overhead.
728
725
729
726
A native API can provide more accurate and comprehensive data with lower overhead.
730
727
@@ -750,6 +747,7 @@ To address this, the API makes `durationThreshold` configurable by the developer
750
747
Further discussion is needed to determine the minimum allowed value for this threshold (e.g., 50ms as suggested) to ensure it remains useful without introducing significant performance costs.
0 commit comments