Merge pull request #1574 from egrs/performance-observer-buffered

Support buffered option in PerformanceObserver.observe()
This commit is contained in:
Karl Seguin
2026-02-18 14:48:15 +08:00
committed by GitHub
3 changed files with 47 additions and 0 deletions

View File

@@ -1243,6 +1243,11 @@ pub fn notifyPerformanceObservers(self: *Page, entry: *Performance.Entry) !void
}
}
try self.schedulePerformanceObserverDelivery();
}
/// Schedules async delivery of performance observer records.
pub fn schedulePerformanceObserverDelivery(self: *Page) !void {
// Already scheduled.
if (self._performance_delivery_scheduled) {
return;

View File

@@ -68,3 +68,31 @@
<script>
testing.expectEqual(['mark', 'measure'], PerformanceObserver.supportedEntryTypes);
</script>
<script id="buffered_option">
{
// Clear marks from previous tests so we get a precise count
performance.clearMarks();
// Create marks BEFORE the observer
performance.mark("early1", { startTime: 1.0 });
performance.mark("early2", { startTime: 2.0 });
let receivedEntries = null;
const observer = new PerformanceObserver((list) => {
receivedEntries = list.getEntries();
});
// With buffered: true, existing marks should be delivered
observer.observe({ type: "mark", buffered: true });
testing.eventually(() => {
testing.expectEqual(true, receivedEntries !== null);
testing.expectEqual(2, receivedEntries.length);
testing.expectEqual("early1", receivedEntries[0].name);
testing.expectEqual("early2", receivedEntries[1].name);
observer.disconnect();
});
}
</script>

View File

@@ -113,6 +113,20 @@ pub fn observe(
// Update interests.
self._interests = interests;
// Deliver existing entries if buffered option is set.
// Per spec, buffered is only valid with the type option, not entryTypes.
// Delivery is async via a queued task, not synchronous.
if (options.buffered and options.type != null and !self.hasRecords()) {
for (page.window._performance._entries.items) |entry| {
if (self.interested(entry)) {
try self._entries.append(page.arena, entry);
}
}
if (self.hasRecords()) {
try page.schedulePerformanceObserverDelivery();
}
}
}
pub fn disconnect(self: *PerformanceObserver, page: *Page) void {