browsertime 17.10.0 → 17.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Browsertime changelog (we do [semantic versioning](https://semver.org))
2
2
 
3
+ ## 17.10.1 - 2022-05-19
4
+ ### Fixed
5
+ * Updated code to collect Interaction To Next Paint [#1952](https://github.com/sitespeedio/browsertime/pull/1952). This new version follow updated version(s) of Google Web Vitals.
6
+
3
7
  ## 17.10.0 - 2022-05-19
4
8
 
5
9
  ### Added
@@ -1,51 +1,32 @@
1
1
  (function () {
2
+
2
3
  // This is an updated version of
3
- // https://github.com/GoogleChrome/web-vitals/blob/next/src/onINP.ts
4
+ // https://github.com/GoogleChrome/web-vitals/blob/64f133590fcac72c1bc042bf7b4ab729d7e03316/src/onINP.ts
5
+ // It was reworked the 19/5-2023
4
6
 
5
7
  const supported = PerformanceObserver.supportedEntryTypes;
6
- if (!supported || supported.indexOf('event') === -1) {
8
+ if (!supported || supported.indexOf('event') === -1 ||  supported.indexOf('first-input') === -1) {
7
9
  return;
8
10
  }
9
-
10
- const observer = new PerformanceObserver(list => {});
11
- // Event Timing entries have their durations rounded to the nearest 8ms,
12
- // so a duration of 40ms would be any event that spans 2.5 or more frames
13
- // at 60Hz. This threshold is chosen to strike a balance between usefulness
14
- // and performance. Running this callback for any interaction that spans
15
- // just one or two frames is likely not worth the insight that could be
16
- // gained.
17
- observer.observe({type: 'event', buffered: true, durationThreshold: 40});
18
- const entries = observer.takeRecords();
19
-
20
- // To prevent unnecessary memory usage on pages with lots of interactions,
21
- // store at most 10 of the longest interactions to consider as INP candidates.
22
- const MAX_INTERACTIONS_TO_CONSIDER = 10;
23
-
24
- // A list of longest interactions on the page (by latency) sorted so the
25
- // longest one is first. The list is as most MAX_INTERACTIONS_TO_CONSIDER long.
26
- let longestInteractionList = [];
27
-
28
- // A mapping of longest interactions by their interaction ID.
29
- // This is used for faster lookup.
30
- const longestInteractionMap = {};
31
-
32
- const getInteractionCountForNavigation = () => {
33
- // I guess the interactionCount is coming in Chrome later on
34
- if (performance.interactionCount) {
35
- return performance.interactionCount;
36
- } else {
37
- const observerForAll = new PerformanceObserver(list => {});
38
- observerForAll.observe({
39
- type: 'event',
40
- buffered: true,
41
- durationThreshold: 0
42
- });
43
- const allEntries = observerForAll.takeRecords();
44
- let interactionCountEstimate = 0;
45
- let minKnownInteractionId = Infinity;
46
- let maxKnownInteractionId = 0;
47
-
48
- for (let e of allEntries) {
11
+ var observe = function observe(type, callback, opts) {
12
+ try {
13
+ if (PerformanceObserver.supportedEntryTypes.includes(type)) {
14
+ var po = new PerformanceObserver(function (list) {
15
+ Promise.resolve().then(function () {
16
+ callback(list.getEntries());
17
+ });
18
+ });
19
+ po.observe(Object.assign({type: type, buffered: true}, opts || {}));
20
+ return po;
21
+ }
22
+ } catch (e) {}
23
+ return;
24
+ };
25
+ var interactionCountEstimate = 0;
26
+ var minKnownInteractionId = Infinity;
27
+ var maxKnownInteractionId = 0;
28
+ var updateEstimate = function updateEstimate(entries) {
29
+ entries.forEach(function (e) {
49
30
  if (e.interactionId) {
50
31
  minKnownInteractionId = Math.min(
51
32
  minKnownInteractionId,
@@ -55,73 +36,117 @@
55
36
  maxKnownInteractionId,
56
37
  e.interactionId
57
38
  );
58
-
59
39
  interactionCountEstimate = maxKnownInteractionId
60
40
  ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1
61
41
  : 0;
62
42
  }
63
- }
64
- return interactionCountEstimate;
65
- }
66
- };
67
-
68
- const estimateP98LongestInteraction = () => {
69
- const candidateInteractionIndex = Math.min(
70
- longestInteractionList.length - 1,
71
- Math.floor(getInteractionCountForNavigation() / 50)
72
- );
73
-
74
- return longestInteractionList[candidateInteractionIndex];
75
- };
76
-
77
- if (entries.length > 0) {
78
- for (let entry of entries) {
79
- const minLongestInteraction =
43
+ });
44
+ };
45
+ var po;
46
+ var getInteractionCount = function getInteractionCount() {
47
+ return po ? interactionCountEstimate : performance.interactionCount || 0;
48
+ };
49
+ var initInteractionCountPolyfill = function initInteractionCountPolyfill() {
50
+ if ('interactionCount' in performance || po) return;
51
+ po = observe('event', updateEstimate, {
52
+ type: 'event',
53
+ buffered: true,
54
+ durationThreshold: 0,
55
+ });
56
+ };
57
+ var prevInteractionCount = 0;
58
+ var getInteractionCountForNavigation =
59
+ function getInteractionCountForNavigation() {
60
+ return getInteractionCount() - prevInteractionCount;
61
+ };
62
+ var MAX_INTERACTIONS_TO_CONSIDER = 10;
63
+ var longestInteractionList = [];
64
+ var longestInteractionMap = {};
65
+ var processEntry = function processEntry(entry) {
66
+ var minLongestInteraction =
80
67
  longestInteractionList[longestInteractionList.length - 1];
81
- const existingInteraction = longestInteractionMap[entry.interactionId];
68
+ var existingInteraction = longestInteractionMap[entry.interactionId];
82
69
  if (
83
70
  existingInteraction ||
84
71
  longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||
85
72
  entry.duration > minLongestInteraction.latency
86
73
  ) {
87
- // If the interaction already exists, update it. Otherwise create one.
88
74
  if (existingInteraction) {
89
- existingInteraction.entries.push(
90
- { id: entry.interactionId,
91
- latency: entry.duration,
92
- name: entry.name
93
- });
75
+ existingInteraction.entries.push(entry);
94
76
  existingInteraction.latency = Math.max(
95
77
  existingInteraction.latency,
96
78
  entry.duration
97
79
  );
98
80
  } else {
99
- const interaction = {
81
+ var interaction = {
100
82
  id: entry.interactionId,
101
83
  latency: entry.duration,
102
- entries: [
103
- {
104
- id: entry.interactionId,
105
- latency: entry.duration,
106
- name: entry.name
107
- }
108
- ]
84
+ entries: [entry],
109
85
  };
110
86
  longestInteractionMap[interaction.id] = interaction;
111
87
  longestInteractionList.push(interaction);
112
88
  }
113
-
114
- // Sort the entries by latency (descending) and keep only the top ten.
115
- longestInteractionList.sort((a, b) => b.latency - a.latency);
89
+ longestInteractionList.sort(function (a, b) {
90
+ return b.latency - a.latency;
91
+ });
116
92
  longestInteractionList
117
93
  .splice(MAX_INTERACTIONS_TO_CONSIDER)
118
- .forEach(i => {
94
+ .forEach(function (i) {
119
95
  delete longestInteractionMap[i.id];
120
96
  });
121
97
  }
98
+ };
99
+ var estimateP98LongestInteraction = function estimateP98LongestInteraction() {
100
+ var candidateInteractionIndex = Math.min(
101
+ longestInteractionList.length - 1,
102
+ Math.floor(getInteractionCountForNavigation() / 50)
103
+ );
104
+ return longestInteractionList[candidateInteractionIndex];
105
+ };
106
+
107
+ var opts = {};
108
+ var metric = {};
109
+ initInteractionCountPolyfill();
110
+ var handleEntries = function handleEntries(entries) {
111
+ entries.forEach(function (entry) {
112
+ if (entry.interactionId) {
113
+ processEntry(entry);
114
+ }
115
+ if (entry.entryType === 'first-input') {
116
+ var noMatchingEntry = !longestInteractionList.some(function (
117
+ interaction
118
+ ) {
119
+ return interaction.entries.some(function (prevEntry) {
120
+ return (
121
+ entry.duration === prevEntry.duration &&
122
+ entry.startTime === prevEntry.startTime
123
+ );
124
+ });
125
+ });
126
+ if (noMatchingEntry) {
127
+ processEntry(entry);
128
+ }
129
+ }
130
+ });
131
+ var inp = estimateP98LongestInteraction();
132
+ if (inp && inp.latency !== metric.value) {
133
+ var cleanedEntries = [];
134
+ for (var entry of inp.entries) {
135
+ console.log(entry);
136
+ cleanedEntries.push({
137
+ id: entry.interactionId,
138
+ latency: entry.duration,
139
+ name: entry.name
140
+ });
141
+ }
142
+ return {latency: inp.latency, entries: cleanedEntries};
143
+ }
144
+ };
145
+ var po = observe('event', handleEntries, {
146
+ durationThreshold: opts.durationThreshold || 40,
147
+ });
148
+ if (po) {
149
+ po.observe({type: 'first-input', buffered: true});
122
150
  }
123
- return estimateP98LongestInteraction();
124
- } else {
125
- // nothing to report
126
- }
127
- })();
151
+ })({});
152
+
@@ -1,41 +1,32 @@
1
1
  (function () {
2
+
2
3
  // This is an updated version of
3
- // https://github.com/GoogleChrome/web-vitals/blob/next/src/onINP.ts
4
+ // https://github.com/GoogleChrome/web-vitals/blob/64f133590fcac72c1bc042bf7b4ab729d7e03316/src/onINP.ts
5
+ // It was reworked the 19/5-2023
4
6
 
5
7
  const supported = PerformanceObserver.supportedEntryTypes;
6
- if (!supported || supported.indexOf('event') === -1) {
8
+ if (!supported || supported.indexOf('event') === -1 ||  supported.indexOf('first-input') === -1) {
7
9
  return;
8
10
  }
9
-
10
- // To prevent unnecessary memory usage on pages with lots of interactions,
11
- // store at most 10 of the longest interactions to consider as INP candidates.
12
- const MAX_INTERACTIONS_TO_CONSIDER = 10;
13
-
14
- // A list of longest interactions on the page (by latency) sorted so the
15
- // longest one is first. The list is as most MAX_INTERACTIONS_TO_CONSIDER long.
16
- let longestInteractionList = [];
17
-
18
- // A mapping of longest interactions by their interaction ID.
19
- // This is used for faster lookup.
20
- const longestInteractionMap = {};
21
-
22
- const getInteractionCountForNavigation = () => {
23
- // I guess the interactionCount is coming in Chrome later on
24
- if (performance.interactionCount) {
25
- return performance.interactionCount;
26
- } else {
27
- const observerForAll = new PerformanceObserver(list => {});
28
- observerForAll.observe({
29
- type: 'event',
30
- buffered: true,
31
- durationThreshold: 0
32
- });
33
- const allEntries = observerForAll.takeRecords();
34
- let interactionCountEstimate = 0;
35
- let minKnownInteractionId = Infinity;
36
- let maxKnownInteractionId = 0;
37
-
38
- for (let e of allEntries) {
11
+ var observe = function observe(type, callback, opts) {
12
+ try {
13
+ if (PerformanceObserver.supportedEntryTypes.includes(type)) {
14
+ var po = new PerformanceObserver(function (list) {
15
+ Promise.resolve().then(function () {
16
+ callback(list.getEntries());
17
+ });
18
+ });
19
+ po.observe(Object.assign({type: type, buffered: true}, opts || {}));
20
+ return po;
21
+ }
22
+ } catch (e) {}
23
+ return;
24
+ };
25
+ var interactionCountEstimate = 0;
26
+ var minKnownInteractionId = Infinity;
27
+ var maxKnownInteractionId = 0;
28
+ var updateEstimate = function updateEstimate(entries) {
29
+ entries.forEach(function (e) {
39
30
  if (e.interactionId) {
40
31
  minKnownInteractionId = Math.min(
41
32
  minKnownInteractionId,
@@ -45,72 +36,107 @@
45
36
  maxKnownInteractionId,
46
37
  e.interactionId
47
38
  );
48
-
49
39
  interactionCountEstimate = maxKnownInteractionId
50
40
  ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1
51
41
  : 0;
52
42
  }
53
- }
54
- return interactionCountEstimate;
55
- }
56
- };
57
-
58
- const estimateP98LongestInteraction = () => {
59
- const candidateInteractionIndex = Math.min(
60
- longestInteractionList.length - 1,
61
- Math.floor(getInteractionCountForNavigation() / 50)
62
- );
63
-
64
- return longestInteractionList[candidateInteractionIndex];
65
- };
66
-
67
- const observer = new PerformanceObserver(list => {});
68
- // Event Timing entries have their durations rounded to the nearest 8ms,
69
- // so a duration of 40ms would be any event that spans 2.5 or more frames
70
- // at 60Hz. This threshold is chosen to strike a balance between usefulness
71
- // and performance. Running this callback for any interaction that spans
72
- // just one or two frames is likely not worth the insight that could be
73
- // gained.
74
- observer.observe({type: 'event', buffered: true, durationThreshold: 40});
75
- const entries = observer.takeRecords();
76
-
77
- if (entries.length > 0) {
78
- for (let entry of entries) {
79
- const minLongestInteraction =
43
+ });
44
+ };
45
+ var po;
46
+ var getInteractionCount = function getInteractionCount() {
47
+ return po ? interactionCountEstimate : performance.interactionCount || 0;
48
+ };
49
+ var initInteractionCountPolyfill = function initInteractionCountPolyfill() {
50
+ if ('interactionCount' in performance || po) return;
51
+ po = observe('event', updateEstimate, {
52
+ type: 'event',
53
+ buffered: true,
54
+ durationThreshold: 0,
55
+ });
56
+ };
57
+ var prevInteractionCount = 0;
58
+ var getInteractionCountForNavigation =
59
+ function getInteractionCountForNavigation() {
60
+ return getInteractionCount() - prevInteractionCount;
61
+ };
62
+ var MAX_INTERACTIONS_TO_CONSIDER = 10;
63
+ var longestInteractionList = [];
64
+ var longestInteractionMap = {};
65
+ var processEntry = function processEntry(entry) {
66
+ var minLongestInteraction =
80
67
  longestInteractionList[longestInteractionList.length - 1];
81
- const existingInteraction = longestInteractionMap[entry.interactionId];
68
+ var existingInteraction = longestInteractionMap[entry.interactionId];
82
69
  if (
83
70
  existingInteraction ||
84
71
  longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||
85
72
  entry.duration > minLongestInteraction.latency
86
73
  ) {
87
- // If the interaction already exists, update it. Otherwise create one.
88
74
  if (existingInteraction) {
75
+ existingInteraction.entries.push(entry);
89
76
  existingInteraction.latency = Math.max(
90
77
  existingInteraction.latency,
91
78
  entry.duration
92
79
  );
93
80
  } else {
94
- const interaction = {
81
+ var interaction = {
95
82
  id: entry.interactionId,
96
- latency: entry.duration
83
+ latency: entry.duration,
84
+ entries: [entry],
97
85
  };
98
86
  longestInteractionMap[interaction.id] = interaction;
99
87
  longestInteractionList.push(interaction);
100
88
  }
101
-
102
- // Sort the entries by latency (descending) and keep only the top ten.
103
- longestInteractionList.sort((a, b) => b.latency - a.latency);
89
+ longestInteractionList.sort(function (a, b) {
90
+ return b.latency - a.latency;
91
+ });
104
92
  longestInteractionList
105
93
  .splice(MAX_INTERACTIONS_TO_CONSIDER)
106
- .forEach(i => {
94
+ .forEach(function (i) {
107
95
  delete longestInteractionMap[i.id];
108
96
  });
109
97
  }
98
+ };
99
+ var estimateP98LongestInteraction = function estimateP98LongestInteraction() {
100
+ var candidateInteractionIndex = Math.min(
101
+ longestInteractionList.length - 1,
102
+ Math.floor(getInteractionCountForNavigation() / 50)
103
+ );
104
+ return longestInteractionList[candidateInteractionIndex];
105
+ };
106
+
107
+ var opts = {};
108
+ initInteractionCountPolyfill();
109
+ var handleEntries = function handleEntries(entries) {
110
+ entries.forEach(function (entry) {
111
+ if (entry.interactionId) {
112
+ processEntry(entry);
113
+ }
114
+ if (entry.entryType === 'first-input') {
115
+ var noMatchingEntry = !longestInteractionList.some(function (
116
+ interaction
117
+ ) {
118
+ return interaction.entries.some(function (prevEntry) {
119
+ return (
120
+ entry.duration === prevEntry.duration &&
121
+ entry.startTime === prevEntry.startTime
122
+ );
123
+ });
124
+ });
125
+ if (noMatchingEntry) {
126
+ processEntry(entry);
127
+ }
128
+ }
129
+ });
130
+ var inp = estimateP98LongestInteraction();
131
+ if (inp && inp.latency !== metric.value) {
132
+ return inp.latency;
133
+ }
134
+ };
135
+ var po = observe('event', handleEntries, {
136
+ durationThreshold: opts.durationThreshold || 40,
137
+ });
138
+ if (po) {
139
+ po.observe({type: 'first-input', buffered: true});
110
140
  }
111
- const inp = estimateP98LongestInteraction();
112
- return inp.latency;
113
- } else {
114
- // nothing to report
115
- }
116
- })();
141
+ })({});
142
+
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "browsertime",
3
3
  "description": "Get performance metrics from your web page using Browsertime.",
4
- "version": "17.10.0",
4
+ "version": "17.10.1",
5
5
  "bin": "./bin/browsertime.js",
6
6
  "type": "module",
7
7
  "dependencies": {