| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent bddaacb commit 6dd5523
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,9 +8,6 @@ | |||
| 8 | 8 | // against an equivalent bag. | |
| 9 | 9 | // | |
| 10 | 10 | // Deliberate deviations from the specs: | |
| 11 | - // - mark/measure `detail` is held by reference (this runtime has no | ||
| 12 | - // structuredClone), so entries retain whatever the caller passed until | ||
| 13 | - // clearMarks()/clearMeasures(); the user-timing buffers are unbounded. | ||
| 14 | 11 | // - Observer callbacks are delivered from a microtask rather than a queued | |
| 15 | 12 | // task. Delivery is still asynchronous relative to mark()/measure(), but it | |
| 16 | 13 | // precedes timer callbacks scheduled in the same turn. | |
@@ -42,6 +39,18 @@ var g = globalThis; | |||
| 42 | 39 | const EventTarget = g.EventTarget; | |
| 43 | 40 | const enqueueMicrotask = g.queueMicrotask; | |
| 44 | 41 | const reportException = g.reportError; | |
| 42 | + // mark/measure `detail` is structured-cloned per spec, so an entry holds a | ||
| 43 | + // snapshot and an uncloneable detail throws DataCloneError. The identity | ||
| 44 | + // fallback keeps this file portable to a runtime that ships the Performance | ||
| 45 | + // API before structuredClone — there, detail degrades to by-reference; the | ||
| 46 | + // user-timing buffers are unbounded either way, so entries retain their | ||
| 47 | + // detail until clearMarks()/clearMeasures(). | ||
| 48 | + const cloneDetail = | ||
| 49 | + typeof g.structuredClone === "function" | ||
| 50 | + ? g.structuredClone | ||
| 51 | + : function (value) { | ||
| 52 | + return value; | ||
| 53 | + }; | ||
| 45 | 54 | ||
| 46 | 55 | // Construction token: interfaces whose constructors the spec marks as not | |
| 47 | 56 | // user-invocable accept instances only from factories inside this module. | |
@@ -135,7 +144,7 @@ class PerformanceMark extends PerformanceEntry { | |||
| 135 | 144 | } | |
| 136 | 145 | } | |
| 137 | 146 | if (markOptions.detail !== undefined && markOptions.detail !== null) { | |
| 138 | - detail = markOptions.detail; | ||
| 147 | + detail = cloneDetail(markOptions.detail); | ||
| 139 | 148 | } | |
| 140 | 149 | } | |
| 141 | 150 | super(kInternal, name, "mark", startTime === undefined ? now() : startTime, 0); | |
@@ -516,7 +525,7 @@ class Performance extends EventTarget { | |||
| 516 | 525 | startTime = 0; | |
| 517 | 526 | } | |
| 518 | 527 | if (o.detail !== undefined && o.detail !== null) { | |
| 519 | - detail = o.detail; | ||
| 528 | + detail = cloneDetail(o.detail); | ||
| 520 | 529 | } | |
| 521 | 530 | } else { | |
| 522 | 531 | endTime = endMark !== undefined ? convertMarkToTimestamp(endMark) : now(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -56,13 +56,10 @@ shares `performance.timeOrigin` as its base. | |||
| 56 | 56 | ||
| 57 | 57 | ## Deviations from the specs | |
| 58 | 58 | ||
| 59 | - - **`detail` is held by reference.** The runtime has no `structuredClone`, so | ||
| 60 | - `mark`/`measure` `detail` values are stored as-is. Mutating the object later | ||
| 61 | - is visible through the entry, and entries retain whatever `detail` | ||
| 62 | - references until `clearMarks()`/`clearMeasures()`. | ||
| 63 | - - **Buffers are unbounded.** Per spec for user timing, but combined with | ||
| 64 | - by-reference `detail` it means a long-lived app marking in a loop should | ||
| 65 | - clear entries periodically. | ||
| 59 | + - **Buffers are unbounded.** Per spec for user timing. `detail` is | ||
| 60 | + structured-cloned at entry creation (per spec — an uncloneable `detail` | ||
| 61 | + throws the `DataCloneError`-named error), so entries hold snapshots, but a | ||
| 62 | + long-lived app marking in a loop should still clear entries periodically. | ||
| 66 | 63 | - **Observer callbacks run from a microtask**, not a queued task: delivery is | |
| 67 | 64 | asynchronous relative to `mark()`/`measure()` but precedes timer callbacks | |
| 68 | 65 | scheduled in the same turn. Callback exceptions are routed to | |
| Back | FazBrowse Home | New Git URL |
0 commit comments