Skip to content

Commit 679ffe6

Browse files
author
Joone Hur
committed
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.
1 parent 617e3a4 commit 679ffe6

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

DelayedMessages/explainer.md

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Web applications frequently use `postMessage` to send messages across different
88

99
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.
1010

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.
1212

1313
# Goals
1414

@@ -26,15 +26,15 @@ This API does not aim to monitor or provide diagnostics for the following types
2626

2727
# Problems
2828

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.
3030

3131
These problems can be broadly categorized into three areas:
3232

3333
1. **Thread being occupied:** The receiving thread is busy executing long-running tasks.
3434
2. **Message queue becoming congested:** Too many messages are enqueued faster than they can be processed.
3535
3. **Serialization/deserialization processes taking significant time:** The data being sent is large or complex, leading to overhead.
3636

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.
3838

3939
## Case 1: Thread Being Occupied
4040

@@ -146,7 +146,7 @@ Manually instrumenting code with `performance.now()` and `event.timeStamp` can h
146146

147147
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.
148148

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.
150150

151151
[Link to live example](https://joone.github.io/web/explainers/delayed_messages/congested/)
152152

@@ -297,7 +297,7 @@ While delays in background tasks like `deleteMail` might be acceptable, delays i
297297

298298
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.
299299

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`.
301301

302302
[Link to live demo](https://joone.github.io/web/explainers/delayed_messages/serialization/)
303303

@@ -400,13 +400,11 @@ onmessage = (event) => {
400400
```
401401
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.
402402

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.
406404

407405
### Summary of Problems
408406

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.
410408

411409
# Proposal: Introducing the Delayed Messages API
412410

@@ -559,7 +557,7 @@ Returns a unique identifier for the execution context (e.g., a string or an inte
559557

560558
#### `PerformanceExecutionContextInfo.name`
561559

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`.
563561

564562
#### `PerformanceExecutionContextInfo.type`
565563

@@ -598,7 +596,7 @@ observer.observe({ type: "delayed-message", durationThreshold: 50, buffered: tru
598596
```
599597
## Examples of a `delayed-message` Performance Entry
600598

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.
602600

603601
By examining `blockedDuration` and the handler execution time (`processingEnd - processingStart`), developers can diagnose the cause:
604602

@@ -724,7 +722,6 @@ Developers can attempt to wrap `postMessage` calls and `onmessage` handlers with
724722

725723
* It's challenging to intercept all messages, especially those from third-party libraries.
726724
* 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.
728725

729726
A native API can provide more accurate and comprehensive data with lower overhead.
730727

@@ -750,6 +747,7 @@ To address this, the API makes `durationThreshold` configurable by the developer
750747
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.
751748

752749
# References
750+
- [Event Timing API](https://w3c.github.io/event-timing/)
753751
- [Extending Long Tasks API to Web Workers](https://github.com/joone/MSEdgeExplainers/blob/add_id_src_type/LongTasks/explainer.md)
754752
- https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongTaskTiming
755753
- https://developer.mozilla.org/en-US/docs/Web/API/PerformanceScriptTiming

0 commit comments

Comments
 (0)