All API introduced in this PR are compliant with web [performance-timeline](https://w3c.github.io/performance-timeline) spec. "performance-timeline" is listed as supported web spec in the doc https://nodejs.org/docs/latest/api/perf_hooks.html#perf_hooks_performance_measurement_apis. Changes summary: 1. Add new supported wpt test subsets: user-timing and performance-timeline. 2. Add support for `Performance.getEntries`, `Performance.getEntriesByName` and `Performance.getEntriesByType` to synchronously fetch buffered performance entries. This means the user should invoke `Performance.clearMarks` and `Performance.clearMeasures` to clear buffered entries to prevent from those entries been kept alive forever. 3. Add support (again after https://github.com/nodejs/node/pull/37136) for `buffered` flags for `PerformanceObserver`. 3. Fixes `PerformanceMark` and `PerformanceMeasure` wpt compliance issues. 4. Only user-created performance entries will be buffered globally. This behavior should be compliant with https://w3c.github.io/timing-entrytypes-registry/#registry. With the new ability to fetch user-created performance entries synchronously, the issues raised in https://github.com/nodejs/diagnostics/issues/464#issuecomment-861920116 could also be fixed. PR-URL: https://github.com/nodejs/node/pull/39297 Reviewed-By: James M Snell <jasnell@gmail.com>
118 lines
3.9 KiB
JavaScript
118 lines
3.9 KiB
JavaScript
// test data
|
|
var testThreshold = 20;
|
|
|
|
var expectedTimes = new Array();
|
|
|
|
function match_entries(entries, index)
|
|
{
|
|
var entry = entries[index];
|
|
var match = self.performance.getEntriesByName("mark")[index];
|
|
assert_equals(entry.name, match.name, "entry.name");
|
|
assert_equals(entry.startTime, match.startTime, "entry.startTime");
|
|
assert_equals(entry.entryType, match.entryType, "entry.entryType");
|
|
assert_equals(entry.duration, match.duration, "entry.duration");
|
|
}
|
|
|
|
function filter_entries_by_type(entryList, entryType)
|
|
{
|
|
var testEntries = new Array();
|
|
|
|
// filter entryList
|
|
for (var i in entryList)
|
|
{
|
|
if (entryList[i].entryType == entryType)
|
|
{
|
|
testEntries.push(entryList[i]);
|
|
}
|
|
}
|
|
|
|
return testEntries;
|
|
}
|
|
|
|
test(function () {
|
|
// create first mark
|
|
self.performance.mark("mark");
|
|
|
|
expectedTimes[0] = self.performance.now();
|
|
|
|
const entries = self.performance.getEntriesByName("mark");
|
|
assert_equals(entries.length, 1);
|
|
}, "Entry 0 is properly created");
|
|
|
|
test(function () {
|
|
// create second, duplicate mark
|
|
self.performance.mark("mark");
|
|
|
|
expectedTimes[1] = self.performance.now();
|
|
|
|
const entries = self.performance.getEntriesByName("mark");
|
|
assert_equals(entries.length, 2);
|
|
|
|
}, "Entry 1 is properly created");
|
|
|
|
function test_mark(index) {
|
|
test(function () {
|
|
const entries = self.performance.getEntriesByName("mark");
|
|
assert_equals(entries[index].name, "mark", "Entry has the proper name");
|
|
}, "Entry " + index + " has the proper name");
|
|
|
|
test(function () {
|
|
const entries = self.performance.getEntriesByName("mark");
|
|
assert_approx_equals(entries[index].startTime, expectedTimes[index], testThreshold);
|
|
}, "Entry " + index + " startTime is approximately correct (up to " + testThreshold +
|
|
"ms difference allowed)");
|
|
|
|
test(function () {
|
|
const entries = self.performance.getEntriesByName("mark");
|
|
assert_equals(entries[index].entryType, "mark");
|
|
}, "Entry " + index + " has the proper entryType");
|
|
|
|
test(function () {
|
|
const entries = self.performance.getEntriesByName("mark");
|
|
assert_equals(entries[index].duration, 0);
|
|
}, "Entry " + index + " duration == 0");
|
|
|
|
test(function () {
|
|
const entries = self.performance.getEntriesByName("mark", "mark");
|
|
assert_equals(entries[index].name, "mark");
|
|
}, "getEntriesByName(\"mark\", \"mark\")[" + index + "] returns an " +
|
|
"object containing a \"mark\" mark");
|
|
|
|
test(function () {
|
|
const entries = self.performance.getEntriesByName("mark", "mark");
|
|
match_entries(entries, index);
|
|
}, "The mark returned by getEntriesByName(\"mark\", \"mark\")[" + index
|
|
+ "] matches the mark returned by " +
|
|
"getEntriesByName(\"mark\")[" + index + "]");
|
|
|
|
test(function () {
|
|
const entries = filter_entries_by_type(self.performance.getEntries(), "mark");
|
|
assert_equals(entries[index].name, "mark");
|
|
}, "getEntries()[" + index + "] returns an " +
|
|
"object containing a \"mark\" mark");
|
|
|
|
test(function () {
|
|
const entries = filter_entries_by_type(self.performance.getEntries(), "mark");
|
|
match_entries(entries, index);
|
|
}, "The mark returned by getEntries()[" + index
|
|
+ "] matches the mark returned by " +
|
|
"getEntriesByName(\"mark\")[" + index + "]");
|
|
|
|
test(function () {
|
|
const entries = self.performance.getEntriesByType("mark");
|
|
assert_equals(entries[index].name, "mark");
|
|
}, "getEntriesByType(\"mark\")[" + index + "] returns an " +
|
|
"object containing a \"mark\" mark");
|
|
|
|
test(function () {
|
|
const entries = self.performance.getEntriesByType("mark");
|
|
match_entries(entries, index);
|
|
}, "The mark returned by getEntriesByType(\"mark\")[" + index
|
|
+ "] matches the mark returned by " +
|
|
"getEntriesByName(\"mark\")[" + index + "]");
|
|
|
|
}
|
|
|
|
for (var i = 0; i < expectedTimes.length; i++) {
|
|
test_mark(i);
|
|
}
|