From e9fdd1c5774733f66027dd0444b302b3d833cf78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vinicius=20Louren=C3=A7o?= <12551007+H4ad@users.noreply.github.com> Date: Sat, 30 Sep 2023 18:44:02 -0300 Subject: [PATCH] perf_hooks: reduce overhead of new resource timings PR-URL: https://github.com/nodejs/node/pull/49837 Reviewed-By: Stephen Belanger Reviewed-By: Yagiz Nizipli --- benchmark/perf_hooks/resourcetiming.js | 2 +- lib/internal/perf/performance_entry.js | 20 ++++++++------ lib/internal/perf/resource_timing.js | 38 ++++++++++++++------------ 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/benchmark/perf_hooks/resourcetiming.js b/benchmark/perf_hooks/resourcetiming.js index ddc40767b16196..51c4778d20065f 100644 --- a/benchmark/perf_hooks/resourcetiming.js +++ b/benchmark/perf_hooks/resourcetiming.js @@ -72,6 +72,6 @@ function main({ n, observe }) { obs.observe({ entryTypes: [observe], buffered: true }); bench.start(); - for (let i = 0; i < 1e5; i++) + for (let i = 0; i < n; i++) test(); } diff --git a/lib/internal/perf/performance_entry.js b/lib/internal/perf/performance_entry.js index aa97a652626606..f6a7520e267c5b 100644 --- a/lib/internal/perf/performance_entry.js +++ b/lib/internal/perf/performance_entry.js @@ -31,10 +31,18 @@ function isPerformanceEntry(obj) { } class PerformanceEntry { - constructor(skipThrowSymbol = undefined) { + constructor( + skipThrowSymbol = undefined, + name = undefined, + type = undefined, + start = undefined, + duration = undefined, + ) { if (skipThrowSymbol !== kSkipThrow) { throw new ERR_ILLEGAL_CONSTRUCTOR(); } + + initPerformanceEntry(this, name, type, start, duration); } get name() { @@ -94,11 +102,7 @@ function initPerformanceEntry(entry, name, type, start, duration) { } function createPerformanceEntry(name, type, start, duration) { - const entry = new PerformanceEntry(kSkipThrow); - - initPerformanceEntry(entry, name, type, start, duration); - - return entry; + return new PerformanceEntry(kSkipThrow, name, type, start, duration); } /** @@ -123,9 +127,8 @@ class PerformanceNodeEntry extends PerformanceEntry { } function createPerformanceNodeEntry(name, type, start, duration, detail) { - const entry = new PerformanceNodeEntry(kSkipThrow); + const entry = new PerformanceNodeEntry(kSkipThrow, name, type, start, duration); - initPerformanceEntry(entry, name, type, start, duration); entry[kDetail] = detail; return entry; @@ -138,4 +141,5 @@ module.exports = { isPerformanceEntry, PerformanceNodeEntry, createPerformanceNodeEntry, + kSkipThrow, }; diff --git a/lib/internal/perf/resource_timing.js b/lib/internal/perf/resource_timing.js index 13f25d0af79cf7..e7c2f1fa448864 100644 --- a/lib/internal/perf/resource_timing.js +++ b/lib/internal/perf/resource_timing.js @@ -3,19 +3,17 @@ const { ObjectDefineProperties, - ObjectSetPrototypeOf, - ReflectConstruct, Symbol, SymbolToStringTag, } = primordials; -const { initPerformanceEntry, PerformanceEntry } = require('internal/perf/performance_entry'); -const assert = require('internal/assert'); -const { enqueue, bufferResourceTiming } = require('internal/perf/observe'); const { codes: { ERR_ILLEGAL_CONSTRUCTOR, }, } = require('internal/errors'); +const { PerformanceEntry, kSkipThrow } = require('internal/perf/performance_entry'); +const assert = require('internal/assert'); +const { enqueue, bufferResourceTiming } = require('internal/perf/observe'); const { validateInternalField } = require('internal/validators'); const { kEnumerableProperty } = require('internal/util'); @@ -25,8 +23,12 @@ const kTimingInfo = Symbol('kTimingInfo'); const kInitiatorType = Symbol('kInitiatorType'); class PerformanceResourceTiming extends PerformanceEntry { - constructor() { - throw new ERR_ILLEGAL_CONSTRUCTOR(); + constructor(skipThrowSymbol = undefined, name = undefined, type = undefined) { + if (skipThrowSymbol !== kSkipThrow) { + throw new ERR_ILLEGAL_CONSTRUCTOR(); + } + + super(skipThrowSymbol, name, type); } get name() { @@ -189,16 +191,17 @@ ObjectDefineProperties(PerformanceResourceTiming.prototype, { }); function createPerformanceResourceTiming(requestedUrl, initiatorType, timingInfo, cacheMode = '') { - return ReflectConstruct(function PerformanceResourceTiming() { - initPerformanceEntry(this, requestedUrl, 'resource'); - this[kInitiatorType] = initiatorType; - this[kRequestedUrl] = requestedUrl; - // https://fetch.spec.whatwg.org/#fetch-timing-info - // This class is using timingInfo assuming it's already validated. - // The spec doesn't say to validate it in the class construction. - this[kTimingInfo] = timingInfo; - this[kCacheMode] = cacheMode; - }, [], PerformanceResourceTiming); + const resourceTiming = new PerformanceResourceTiming(kSkipThrow, requestedUrl, 'resource'); + + resourceTiming[kInitiatorType] = initiatorType; + resourceTiming[kRequestedUrl] = requestedUrl; + // https://fetch.spec.whatwg.org/#fetch-timing-info + // This class is using timingInfo assuming it's already validated. + // The spec doesn't say to validate it in the class construction. + resourceTiming[kTimingInfo] = timingInfo; + resourceTiming[kCacheMode] = cacheMode; + + return resourceTiming; } // https://w3c.github.io/resource-timing/#dfn-mark-resource-timing @@ -221,7 +224,6 @@ function markResourceTiming( cacheMode, ); - ObjectSetPrototypeOf(resource, PerformanceResourceTiming.prototype); enqueue(resource); bufferResourceTiming(resource); return resource;