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.
- Update congested example to remove IndexedDB references
Copy file name to clipboardExpand all lines: DelayedMessages/explainer.md
+28-29Lines changed: 28 additions & 29 deletions
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,13 +146,13 @@ 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
153
153
### index.html
154
154
155
-
```js
155
+
```html
156
156
<!doctype html>
157
157
<htmllang="en">
158
158
<head>
@@ -161,12 +161,13 @@ The following example codes demonstrates this situation, where multiple `deleteM
161
161
<title>An example of a message queue experiencing congestion</title>
In main.js, the email application sends 10 deleteEmail tasks every 30 ms to clear junk emails, keeping the worker occupied with intensive processing. Shortly after, the user requests to check their emails, requiring an immediate response.
@@ -175,12 +176,12 @@ In main.js, the email application sends 10 deleteEmail tasks every 30 ms to clea
@@ -209,7 +210,7 @@ function sendTasksToWorker() {
209
210
210
211
### worker.js
211
212
212
-
The Web Worker's `onmessage` handler processes `openIndexDB`, `deleteMail`, and `readMails` tasks received from the main thread. Each task requires 50ms to complete."
213
+
The Web Worker's `onmessage` handler processes `openMailStorage`, `deleteMail`, and `readMails` tasks received from the main thread. Each task requires 50ms to complete."
@@ -297,7 +298,7 @@ While delays in background tasks like `deleteMail` might be acceptable, delays i
297
298
298
299
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
300
300
-
The following example code demonstrate the delay introduced by serializing/deserializing a large JSON object during postMessage.
301
+
The following example code demonstrate the delay introduced by serializing/deserializing a large JSON object during `postMessage`.
301
302
302
303
[Link to live demo](https://joone.github.io/web/explainers/delayed_messages/serialization/)
303
304
@@ -400,13 +401,11 @@ onmessage = (event) => {
400
401
```
401
402
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
403
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.
404
+
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
405
407
406
### Summary of Problems
408
407
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.
408
+
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
409
411
410
# Proposal: Introducing the Delayed Messages API
412
411
@@ -559,7 +558,7 @@ Returns a unique identifier for the execution context (e.g., a string or an inte
559
558
560
559
#### `PerformanceExecutionContextInfo.name`
561
560
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`.
561
+
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
599
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.
600
+
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
601
603
602
By examining `blockedDuration` and the handler execution time (`processingEnd - processingStart`), developers can diagnose the cause:
604
603
@@ -724,7 +723,6 @@ Developers can attempt to wrap `postMessage` calls and `onmessage` handlers with
724
723
725
724
* It's challenging to intercept all messages, especially those from third-party libraries.
726
725
* 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
726
729
727
A native API can provide more accurate and comprehensive data with lower overhead.
730
728
@@ -750,6 +748,7 @@ To address this, the API makes `durationThreshold` configurable by the developer
750
748
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