Skip to content

Commit

Permalink
perf_hooks: reduce overhead of new resource timings
Browse files Browse the repository at this point in the history
PR-URL: nodejs#49837
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
  • Loading branch information
H4ad authored and debadree25 committed Apr 15, 2024
1 parent b19350e commit e9fdd1c
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 27 deletions.
2 changes: 1 addition & 1 deletion benchmark/perf_hooks/resourcetiming.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
20 changes: 12 additions & 8 deletions lib/internal/perf/performance_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
}

/**
Expand All @@ -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;
Expand All @@ -138,4 +141,5 @@ module.exports = {
isPerformanceEntry,
PerformanceNodeEntry,
createPerformanceNodeEntry,
kSkipThrow,
};
38 changes: 20 additions & 18 deletions lib/internal/perf/resource_timing.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand All @@ -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() {
Expand Down Expand Up @@ -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
Expand All @@ -221,7 +224,6 @@ function markResourceTiming(
cacheMode,
);

ObjectSetPrototypeOf(resource, PerformanceResourceTiming.prototype);
enqueue(resource);
bufferResourceTiming(resource);
return resource;
Expand Down

0 comments on commit e9fdd1c

Please sign in to comment.