@atlaskit/react-ufo 3.13.28 → 3.14.0
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 +8 -0
- package/dist/cjs/create-payload/index.js +3 -1
- package/dist/cjs/interaction-metrics-init/index.js +3 -0
- package/dist/cjs/machine-utilisation/index.js +82 -9
- package/dist/es2019/create-payload/index.js +4 -1
- package/dist/es2019/interaction-metrics-init/index.js +4 -1
- package/dist/es2019/machine-utilisation/index.js +72 -5
- package/dist/esm/create-payload/index.js +4 -2
- package/dist/esm/interaction-metrics-init/index.js +4 -1
- package/dist/esm/machine-utilisation/index.js +76 -8
- package/dist/types/create-payload/index.d.ts +160 -0
- package/dist/types/machine-utilisation/index.d.ts +10 -1
- package/dist/types/machine-utilisation/types.d.ts +6 -0
- package/dist/types-ts4.5/create-payload/index.d.ts +160 -0
- package/dist/types-ts4.5/machine-utilisation/index.d.ts +10 -1
- package/dist/types-ts4.5/machine-utilisation/types.d.ts +6 -0
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/ufo-interaction-ignore
|
|
2
2
|
|
|
3
|
+
## 3.14.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#176314](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/176314)
|
|
8
|
+
[`9c32e96190532`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9c32e96190532) -
|
|
9
|
+
report memory usage via UFO
|
|
10
|
+
|
|
3
11
|
## 3.13.28
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -809,7 +809,7 @@ function _createInteractionMetricsPayload() {
|
|
|
809
809
|
source: 'measured',
|
|
810
810
|
tags: ['observability'],
|
|
811
811
|
attributes: {
|
|
812
|
-
properties: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
812
|
+
properties: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
813
813
|
// basic
|
|
814
814
|
'event:hostname': ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.hostname) || 'unknown',
|
|
815
815
|
'event:product': config.product,
|
|
@@ -824,6 +824,8 @@ function _createInteractionMetricsPayload() {
|
|
|
824
824
|
'experience:name': newUFOName
|
|
825
825
|
}, (0, _platformFeatureFlags.fg)('platform_ufo_report_cpu_usage') ? {
|
|
826
826
|
'event:cpu:usage': (0, _machineUtilisation.createPressureStateReport)(interaction.start, interaction.end)
|
|
827
|
+
} : {}), (0, _platformFeatureFlags.fg)('platform_ufo_report_memory_usage') ? {
|
|
828
|
+
'event:memory:usage': (0, _machineUtilisation.createMemoryStateReport)(interaction.start, interaction.end)
|
|
827
829
|
} : {}), getBrowserMetadata()), getSSRProperties(type)), getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime)), getPPSMetrics(interaction)), paintMetrics), getNavigationMetrics(type)), vcMetrics), experimentalMetrics), (_config$additionalPay = config.additionalPayloadData) === null || _config$additionalPay === void 0 ? void 0 : _config$additionalPay.call(config, interaction)), getTracingContextData(interaction)), getStylesheetMetrics()), getErrorCounts(interaction)), {}, {
|
|
828
830
|
interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
829
831
|
namePrefix: config.namePrefix || '',
|
|
@@ -87,6 +87,9 @@ function init(analyticsWebClientAsync, config) {
|
|
|
87
87
|
if ((0, _platformFeatureFlags.fg)('platform_ufo_report_cpu_usage')) {
|
|
88
88
|
(0, _machineUtilisation.initialisePressureObserver)();
|
|
89
89
|
}
|
|
90
|
+
if ((0, _platformFeatureFlags.fg)('platform_ufo_report_memory_usage')) {
|
|
91
|
+
(0, _machineUtilisation.initialiseMemoryObserver)();
|
|
92
|
+
}
|
|
90
93
|
(0, _config.setUFOConfig)(config);
|
|
91
94
|
if ((_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled) {
|
|
92
95
|
var _config$experimentalI;
|
|
@@ -4,33 +4,49 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
+
exports.createMemoryStateReport = createMemoryStateReport;
|
|
7
8
|
exports.createPressureStateReport = createPressureStateReport;
|
|
9
|
+
exports.disconnectMemoryObserver = disconnectMemoryObserver;
|
|
8
10
|
exports.disconnectPressureObserver = disconnectPressureObserver;
|
|
11
|
+
exports.initialiseMemoryObserver = initialiseMemoryObserver;
|
|
9
12
|
exports.initialisePressureObserver = initialisePressureObserver;
|
|
10
|
-
exports.
|
|
13
|
+
exports.removeOldMemoryBufferRecords = removeOldMemoryBufferRecords;
|
|
14
|
+
exports.removeOldPressureBufferRecords = removeOldPressureBufferRecords;
|
|
15
|
+
exports.resetMemoryRecordBuffer = resetMemoryRecordBuffer;
|
|
11
16
|
exports.resetPressureRecordBuffer = resetPressureRecordBuffer;
|
|
12
17
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
13
18
|
var BUFFER_MAX_LENGTH = 1000; // ensure we don't blow up this buffer
|
|
14
19
|
var pressureRecordBuffer = [];
|
|
15
20
|
var pressureObserver = null;
|
|
21
|
+
var memoryRecordBuffer = [];
|
|
22
|
+
var memoryInterval;
|
|
16
23
|
function resetPressureRecordBuffer() {
|
|
17
24
|
pressureRecordBuffer.length = 0;
|
|
18
25
|
}
|
|
19
|
-
function
|
|
26
|
+
function resetMemoryRecordBuffer() {
|
|
27
|
+
memoryRecordBuffer.length = 0;
|
|
28
|
+
}
|
|
29
|
+
function removeOldPressureBufferRecords(filter) {
|
|
20
30
|
pressureRecordBuffer = pressureRecordBuffer.filter(function (_ref) {
|
|
21
31
|
var time = _ref.time;
|
|
22
32
|
return time > filter;
|
|
23
33
|
});
|
|
24
34
|
}
|
|
35
|
+
function removeOldMemoryBufferRecords(filter) {
|
|
36
|
+
memoryRecordBuffer = memoryRecordBuffer.filter(function (_ref2) {
|
|
37
|
+
var time = _ref2.time;
|
|
38
|
+
return time > filter;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
25
41
|
function createPressureStateReport(start, end) {
|
|
26
42
|
try {
|
|
27
43
|
// To differentiate between the API not available, vs no PressureRecords added
|
|
28
44
|
if (!('PressureObserver' in globalThis)) {
|
|
29
45
|
return null;
|
|
30
46
|
}
|
|
31
|
-
var pressureStateCount = pressureRecordBuffer.reduce(function (pressureReport,
|
|
32
|
-
var time =
|
|
33
|
-
state =
|
|
47
|
+
var pressureStateCount = pressureRecordBuffer.reduce(function (pressureReport, _ref3) {
|
|
48
|
+
var time = _ref3.time,
|
|
49
|
+
state = _ref3.state;
|
|
34
50
|
if (time >= start && time <= end) {
|
|
35
51
|
pressureReport[state] += 1;
|
|
36
52
|
}
|
|
@@ -44,7 +60,7 @@ function createPressureStateReport(start, end) {
|
|
|
44
60
|
var pressureStateTotal = Object.values(pressureStateCount).reduce(function (total, count) {
|
|
45
61
|
return total + count;
|
|
46
62
|
}) || 1;
|
|
47
|
-
|
|
63
|
+
removeOldPressureBufferRecords(end);
|
|
48
64
|
return {
|
|
49
65
|
count: pressureStateCount,
|
|
50
66
|
percentage: {
|
|
@@ -58,24 +74,81 @@ function createPressureStateReport(start, end) {
|
|
|
58
74
|
return null;
|
|
59
75
|
}
|
|
60
76
|
}
|
|
77
|
+
function convertBytesToMegabytes(bytes) {
|
|
78
|
+
return Math.round(Math.round(bytes / (1024 * 1024) * 100) / 100);
|
|
79
|
+
}
|
|
80
|
+
function createMemoryStateReport(start, end) {
|
|
81
|
+
try {
|
|
82
|
+
if (!('memory' in performance)) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
var accumulatedMemoryUsage = memoryRecordBuffer.reduce(function (acc, snapshot) {
|
|
86
|
+
if (snapshot.time >= start && snapshot.time <= end) {
|
|
87
|
+
acc.totalJSHeapSize += snapshot.totalJSHeapSize;
|
|
88
|
+
acc.usedJSHeapSize += snapshot.usedJSHeapSize;
|
|
89
|
+
acc.snapshotCount += 1;
|
|
90
|
+
}
|
|
91
|
+
return acc;
|
|
92
|
+
}, {
|
|
93
|
+
totalJSHeapSize: 0,
|
|
94
|
+
usedJSHeapSize: 0,
|
|
95
|
+
snapshotCount: 0
|
|
96
|
+
});
|
|
97
|
+
var memoryStateReport = {
|
|
98
|
+
jsHeapSizeLimitInMB: convertBytesToMegabytes(memoryRecordBuffer[0].jsHeapSizeLimit),
|
|
99
|
+
// just use the first record, since this value always remains the same over time
|
|
100
|
+
avgTotalJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.totalJSHeapSize / accumulatedMemoryUsage.snapshotCount),
|
|
101
|
+
avgUsedJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.usedJSHeapSize / accumulatedMemoryUsage.snapshotCount)
|
|
102
|
+
};
|
|
103
|
+
removeOldMemoryBufferRecords(end);
|
|
104
|
+
return memoryStateReport;
|
|
105
|
+
} catch (_unused2) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
61
109
|
function initialisePressureObserver() {
|
|
62
110
|
try {
|
|
63
111
|
if ('PressureObserver' in globalThis) {
|
|
64
|
-
var _pressureObserver$obs;
|
|
65
112
|
pressureObserver = new PressureObserver(function (records) {
|
|
66
113
|
if (pressureRecordBuffer.length + records.length <= BUFFER_MAX_LENGTH) {
|
|
67
114
|
var _pressureRecordBuffer;
|
|
68
115
|
(_pressureRecordBuffer = pressureRecordBuffer).push.apply(_pressureRecordBuffer, (0, _toConsumableArray2.default)(records));
|
|
69
116
|
}
|
|
70
117
|
});
|
|
71
|
-
|
|
118
|
+
pressureObserver.observe('cpu', {
|
|
72
119
|
sampleInterval: 100
|
|
73
|
-
})
|
|
120
|
+
}).catch();
|
|
74
121
|
}
|
|
75
122
|
} catch (err) {
|
|
76
123
|
/* do nothing, this is a best efforts metric */
|
|
77
124
|
}
|
|
78
125
|
}
|
|
126
|
+
function initialiseMemoryObserver() {
|
|
127
|
+
try {
|
|
128
|
+
// only set up the interval if `performance.memory` is available in the browser
|
|
129
|
+
if ('memory' in performance) {
|
|
130
|
+
memoryInterval = setInterval(function () {
|
|
131
|
+
// another check of `performance.memory` availability to satisfy typescript
|
|
132
|
+
if ('memory' in performance) {
|
|
133
|
+
var memory = performance.memory;
|
|
134
|
+
if (memoryRecordBuffer.length <= BUFFER_MAX_LENGTH) {
|
|
135
|
+
memoryRecordBuffer.push({
|
|
136
|
+
time: performance.now(),
|
|
137
|
+
jsHeapSizeLimit: memory.jsHeapSizeLimit,
|
|
138
|
+
totalJSHeapSize: memory.totalJSHeapSize,
|
|
139
|
+
usedJSHeapSize: memory.usedJSHeapSize
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}, 100);
|
|
144
|
+
}
|
|
145
|
+
} catch (_unused3) {
|
|
146
|
+
/* do nothing, this is a best efforts metric */
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function disconnectMemoryObserver() {
|
|
150
|
+
clearInterval(memoryInterval);
|
|
151
|
+
}
|
|
79
152
|
function disconnectPressureObserver() {
|
|
80
153
|
var _pressureObserver;
|
|
81
154
|
(_pressureObserver = pressureObserver) === null || _pressureObserver === void 0 || _pressureObserver.disconnect();
|
|
@@ -11,7 +11,7 @@ import { getGlobalErrorCount } from '../global-error-handler';
|
|
|
11
11
|
import { getPageVisibilityState } from '../hidden-timing';
|
|
12
12
|
import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
|
|
13
13
|
import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
|
|
14
|
-
import { createPressureStateReport } from '../machine-utilisation';
|
|
14
|
+
import { createMemoryStateReport, createPressureStateReport } from '../machine-utilisation';
|
|
15
15
|
import * as resourceTiming from '../resource-timing';
|
|
16
16
|
import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
|
|
17
17
|
import { roundEpsilon } from '../round-number';
|
|
@@ -803,6 +803,9 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
|
|
|
803
803
|
...(fg('platform_ufo_report_cpu_usage') ? {
|
|
804
804
|
'event:cpu:usage': createPressureStateReport(interaction.start, interaction.end)
|
|
805
805
|
} : {}),
|
|
806
|
+
...(fg('platform_ufo_report_memory_usage') ? {
|
|
807
|
+
'event:memory:usage': createMemoryStateReport(interaction.start, interaction.end)
|
|
808
|
+
} : {}),
|
|
806
809
|
// root
|
|
807
810
|
...getBrowserMetadata(),
|
|
808
811
|
...getSSRProperties(type),
|
|
@@ -5,7 +5,7 @@ import { experimentalVC, sinkExperimentalHandler } from '../create-experimental-
|
|
|
5
5
|
import { setupHiddenTimingCapture } from '../hidden-timing';
|
|
6
6
|
import { postInteractionLog, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
|
|
7
7
|
import { getPerformanceObserver } from '../interactions-performance-observer';
|
|
8
|
-
import { initialisePressureObserver } from '../machine-utilisation';
|
|
8
|
+
import { initialiseMemoryObserver, initialisePressureObserver } from '../machine-utilisation';
|
|
9
9
|
import { getVCObserver } from '../vc';
|
|
10
10
|
import scheduleIdleCallback from './schedule-idle-callback';
|
|
11
11
|
let initialized = false;
|
|
@@ -77,6 +77,9 @@ export function init(analyticsWebClientAsync, config) {
|
|
|
77
77
|
if (fg('platform_ufo_report_cpu_usage')) {
|
|
78
78
|
initialisePressureObserver();
|
|
79
79
|
}
|
|
80
|
+
if (fg('platform_ufo_report_memory_usage')) {
|
|
81
|
+
initialiseMemoryObserver();
|
|
82
|
+
}
|
|
80
83
|
setUFOConfig(config);
|
|
81
84
|
if ((_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled) {
|
|
82
85
|
var _config$experimentalI;
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
const BUFFER_MAX_LENGTH = 1000; // ensure we don't blow up this buffer
|
|
2
2
|
let pressureRecordBuffer = [];
|
|
3
3
|
let pressureObserver = null;
|
|
4
|
+
let memoryRecordBuffer = [];
|
|
5
|
+
let memoryInterval;
|
|
4
6
|
export function resetPressureRecordBuffer() {
|
|
5
7
|
pressureRecordBuffer.length = 0;
|
|
6
8
|
}
|
|
7
|
-
export function
|
|
9
|
+
export function resetMemoryRecordBuffer() {
|
|
10
|
+
memoryRecordBuffer.length = 0;
|
|
11
|
+
}
|
|
12
|
+
export function removeOldPressureBufferRecords(filter) {
|
|
8
13
|
pressureRecordBuffer = pressureRecordBuffer.filter(({
|
|
9
14
|
time
|
|
10
15
|
}) => time > filter);
|
|
11
16
|
}
|
|
17
|
+
export function removeOldMemoryBufferRecords(filter) {
|
|
18
|
+
memoryRecordBuffer = memoryRecordBuffer.filter(({
|
|
19
|
+
time
|
|
20
|
+
}) => time > filter);
|
|
21
|
+
}
|
|
12
22
|
export function createPressureStateReport(start, end) {
|
|
13
23
|
try {
|
|
14
24
|
// To differentiate between the API not available, vs no PressureRecords added
|
|
@@ -30,7 +40,7 @@ export function createPressureStateReport(start, end) {
|
|
|
30
40
|
critical: 0
|
|
31
41
|
});
|
|
32
42
|
const pressureStateTotal = Object.values(pressureStateCount).reduce((total, count) => total + count) || 1;
|
|
33
|
-
|
|
43
|
+
removeOldPressureBufferRecords(end);
|
|
34
44
|
return {
|
|
35
45
|
count: pressureStateCount,
|
|
36
46
|
percentage: {
|
|
@@ -44,23 +54,80 @@ export function createPressureStateReport(start, end) {
|
|
|
44
54
|
return null;
|
|
45
55
|
}
|
|
46
56
|
}
|
|
57
|
+
function convertBytesToMegabytes(bytes) {
|
|
58
|
+
return Math.round(Math.round(bytes / (1024 * 1024) * 100) / 100);
|
|
59
|
+
}
|
|
60
|
+
export function createMemoryStateReport(start, end) {
|
|
61
|
+
try {
|
|
62
|
+
if (!('memory' in performance)) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
const accumulatedMemoryUsage = memoryRecordBuffer.reduce((acc, snapshot) => {
|
|
66
|
+
if (snapshot.time >= start && snapshot.time <= end) {
|
|
67
|
+
acc.totalJSHeapSize += snapshot.totalJSHeapSize;
|
|
68
|
+
acc.usedJSHeapSize += snapshot.usedJSHeapSize;
|
|
69
|
+
acc.snapshotCount += 1;
|
|
70
|
+
}
|
|
71
|
+
return acc;
|
|
72
|
+
}, {
|
|
73
|
+
totalJSHeapSize: 0,
|
|
74
|
+
usedJSHeapSize: 0,
|
|
75
|
+
snapshotCount: 0
|
|
76
|
+
});
|
|
77
|
+
const memoryStateReport = {
|
|
78
|
+
jsHeapSizeLimitInMB: convertBytesToMegabytes(memoryRecordBuffer[0].jsHeapSizeLimit),
|
|
79
|
+
// just use the first record, since this value always remains the same over time
|
|
80
|
+
avgTotalJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.totalJSHeapSize / accumulatedMemoryUsage.snapshotCount),
|
|
81
|
+
avgUsedJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.usedJSHeapSize / accumulatedMemoryUsage.snapshotCount)
|
|
82
|
+
};
|
|
83
|
+
removeOldMemoryBufferRecords(end);
|
|
84
|
+
return memoryStateReport;
|
|
85
|
+
} catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
47
89
|
export function initialisePressureObserver() {
|
|
48
90
|
try {
|
|
49
91
|
if ('PressureObserver' in globalThis) {
|
|
50
|
-
var _pressureObserver$obs;
|
|
51
92
|
pressureObserver = new PressureObserver(records => {
|
|
52
93
|
if (pressureRecordBuffer.length + records.length <= BUFFER_MAX_LENGTH) {
|
|
53
94
|
pressureRecordBuffer.push(...records);
|
|
54
95
|
}
|
|
55
96
|
});
|
|
56
|
-
|
|
97
|
+
pressureObserver.observe('cpu', {
|
|
57
98
|
sampleInterval: 100
|
|
58
|
-
})
|
|
99
|
+
}).catch();
|
|
59
100
|
}
|
|
60
101
|
} catch (err) {
|
|
61
102
|
/* do nothing, this is a best efforts metric */
|
|
62
103
|
}
|
|
63
104
|
}
|
|
105
|
+
export function initialiseMemoryObserver() {
|
|
106
|
+
try {
|
|
107
|
+
// only set up the interval if `performance.memory` is available in the browser
|
|
108
|
+
if ('memory' in performance) {
|
|
109
|
+
memoryInterval = setInterval(() => {
|
|
110
|
+
// another check of `performance.memory` availability to satisfy typescript
|
|
111
|
+
if ('memory' in performance) {
|
|
112
|
+
const memory = performance.memory;
|
|
113
|
+
if (memoryRecordBuffer.length <= BUFFER_MAX_LENGTH) {
|
|
114
|
+
memoryRecordBuffer.push({
|
|
115
|
+
time: performance.now(),
|
|
116
|
+
jsHeapSizeLimit: memory.jsHeapSizeLimit,
|
|
117
|
+
totalJSHeapSize: memory.totalJSHeapSize,
|
|
118
|
+
usedJSHeapSize: memory.usedJSHeapSize
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}, 100);
|
|
123
|
+
}
|
|
124
|
+
} catch {
|
|
125
|
+
/* do nothing, this is a best efforts metric */
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export function disconnectMemoryObserver() {
|
|
129
|
+
clearInterval(memoryInterval);
|
|
130
|
+
}
|
|
64
131
|
export function disconnectPressureObserver() {
|
|
65
132
|
var _pressureObserver;
|
|
66
133
|
(_pressureObserver = pressureObserver) === null || _pressureObserver === void 0 ? void 0 : _pressureObserver.disconnect();
|
|
@@ -23,7 +23,7 @@ import { getGlobalErrorCount } from '../global-error-handler';
|
|
|
23
23
|
import { getPageVisibilityState } from '../hidden-timing';
|
|
24
24
|
import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
|
|
25
25
|
import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
|
|
26
|
-
import { createPressureStateReport } from '../machine-utilisation';
|
|
26
|
+
import { createMemoryStateReport, createPressureStateReport } from '../machine-utilisation';
|
|
27
27
|
import * as resourceTiming from '../resource-timing';
|
|
28
28
|
import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
|
|
29
29
|
import { roundEpsilon } from '../round-number';
|
|
@@ -799,7 +799,7 @@ function _createInteractionMetricsPayload() {
|
|
|
799
799
|
source: 'measured',
|
|
800
800
|
tags: ['observability'],
|
|
801
801
|
attributes: {
|
|
802
|
-
properties: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
802
|
+
properties: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
803
803
|
// basic
|
|
804
804
|
'event:hostname': ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.hostname) || 'unknown',
|
|
805
805
|
'event:product': config.product,
|
|
@@ -814,6 +814,8 @@ function _createInteractionMetricsPayload() {
|
|
|
814
814
|
'experience:name': newUFOName
|
|
815
815
|
}, fg('platform_ufo_report_cpu_usage') ? {
|
|
816
816
|
'event:cpu:usage': createPressureStateReport(interaction.start, interaction.end)
|
|
817
|
+
} : {}), fg('platform_ufo_report_memory_usage') ? {
|
|
818
|
+
'event:memory:usage': createMemoryStateReport(interaction.start, interaction.end)
|
|
817
819
|
} : {}), getBrowserMetadata()), getSSRProperties(type)), getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime)), getPPSMetrics(interaction)), paintMetrics), getNavigationMetrics(type)), vcMetrics), experimentalMetrics), (_config$additionalPay = config.additionalPayloadData) === null || _config$additionalPay === void 0 ? void 0 : _config$additionalPay.call(config, interaction)), getTracingContextData(interaction)), getStylesheetMetrics()), getErrorCounts(interaction)), {}, {
|
|
818
820
|
interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
819
821
|
namePrefix: config.namePrefix || '',
|
|
@@ -6,7 +6,7 @@ import { experimentalVC, sinkExperimentalHandler } from '../create-experimental-
|
|
|
6
6
|
import { setupHiddenTimingCapture } from '../hidden-timing';
|
|
7
7
|
import { postInteractionLog, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
|
|
8
8
|
import { getPerformanceObserver } from '../interactions-performance-observer';
|
|
9
|
-
import { initialisePressureObserver } from '../machine-utilisation';
|
|
9
|
+
import { initialiseMemoryObserver, initialisePressureObserver } from '../machine-utilisation';
|
|
10
10
|
import { getVCObserver } from '../vc';
|
|
11
11
|
import scheduleIdleCallback from './schedule-idle-callback';
|
|
12
12
|
var initialized = false;
|
|
@@ -78,6 +78,9 @@ export function init(analyticsWebClientAsync, config) {
|
|
|
78
78
|
if (fg('platform_ufo_report_cpu_usage')) {
|
|
79
79
|
initialisePressureObserver();
|
|
80
80
|
}
|
|
81
|
+
if (fg('platform_ufo_report_memory_usage')) {
|
|
82
|
+
initialiseMemoryObserver();
|
|
83
|
+
}
|
|
81
84
|
setUFOConfig(config);
|
|
82
85
|
if ((_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled) {
|
|
83
86
|
var _config$experimentalI;
|
|
@@ -2,24 +2,35 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
|
2
2
|
var BUFFER_MAX_LENGTH = 1000; // ensure we don't blow up this buffer
|
|
3
3
|
var pressureRecordBuffer = [];
|
|
4
4
|
var pressureObserver = null;
|
|
5
|
+
var memoryRecordBuffer = [];
|
|
6
|
+
var memoryInterval;
|
|
5
7
|
export function resetPressureRecordBuffer() {
|
|
6
8
|
pressureRecordBuffer.length = 0;
|
|
7
9
|
}
|
|
8
|
-
export function
|
|
10
|
+
export function resetMemoryRecordBuffer() {
|
|
11
|
+
memoryRecordBuffer.length = 0;
|
|
12
|
+
}
|
|
13
|
+
export function removeOldPressureBufferRecords(filter) {
|
|
9
14
|
pressureRecordBuffer = pressureRecordBuffer.filter(function (_ref) {
|
|
10
15
|
var time = _ref.time;
|
|
11
16
|
return time > filter;
|
|
12
17
|
});
|
|
13
18
|
}
|
|
19
|
+
export function removeOldMemoryBufferRecords(filter) {
|
|
20
|
+
memoryRecordBuffer = memoryRecordBuffer.filter(function (_ref2) {
|
|
21
|
+
var time = _ref2.time;
|
|
22
|
+
return time > filter;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
14
25
|
export function createPressureStateReport(start, end) {
|
|
15
26
|
try {
|
|
16
27
|
// To differentiate between the API not available, vs no PressureRecords added
|
|
17
28
|
if (!('PressureObserver' in globalThis)) {
|
|
18
29
|
return null;
|
|
19
30
|
}
|
|
20
|
-
var pressureStateCount = pressureRecordBuffer.reduce(function (pressureReport,
|
|
21
|
-
var time =
|
|
22
|
-
state =
|
|
31
|
+
var pressureStateCount = pressureRecordBuffer.reduce(function (pressureReport, _ref3) {
|
|
32
|
+
var time = _ref3.time,
|
|
33
|
+
state = _ref3.state;
|
|
23
34
|
if (time >= start && time <= end) {
|
|
24
35
|
pressureReport[state] += 1;
|
|
25
36
|
}
|
|
@@ -33,7 +44,7 @@ export function createPressureStateReport(start, end) {
|
|
|
33
44
|
var pressureStateTotal = Object.values(pressureStateCount).reduce(function (total, count) {
|
|
34
45
|
return total + count;
|
|
35
46
|
}) || 1;
|
|
36
|
-
|
|
47
|
+
removeOldPressureBufferRecords(end);
|
|
37
48
|
return {
|
|
38
49
|
count: pressureStateCount,
|
|
39
50
|
percentage: {
|
|
@@ -47,24 +58,81 @@ export function createPressureStateReport(start, end) {
|
|
|
47
58
|
return null;
|
|
48
59
|
}
|
|
49
60
|
}
|
|
61
|
+
function convertBytesToMegabytes(bytes) {
|
|
62
|
+
return Math.round(Math.round(bytes / (1024 * 1024) * 100) / 100);
|
|
63
|
+
}
|
|
64
|
+
export function createMemoryStateReport(start, end) {
|
|
65
|
+
try {
|
|
66
|
+
if (!('memory' in performance)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
var accumulatedMemoryUsage = memoryRecordBuffer.reduce(function (acc, snapshot) {
|
|
70
|
+
if (snapshot.time >= start && snapshot.time <= end) {
|
|
71
|
+
acc.totalJSHeapSize += snapshot.totalJSHeapSize;
|
|
72
|
+
acc.usedJSHeapSize += snapshot.usedJSHeapSize;
|
|
73
|
+
acc.snapshotCount += 1;
|
|
74
|
+
}
|
|
75
|
+
return acc;
|
|
76
|
+
}, {
|
|
77
|
+
totalJSHeapSize: 0,
|
|
78
|
+
usedJSHeapSize: 0,
|
|
79
|
+
snapshotCount: 0
|
|
80
|
+
});
|
|
81
|
+
var memoryStateReport = {
|
|
82
|
+
jsHeapSizeLimitInMB: convertBytesToMegabytes(memoryRecordBuffer[0].jsHeapSizeLimit),
|
|
83
|
+
// just use the first record, since this value always remains the same over time
|
|
84
|
+
avgTotalJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.totalJSHeapSize / accumulatedMemoryUsage.snapshotCount),
|
|
85
|
+
avgUsedJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.usedJSHeapSize / accumulatedMemoryUsage.snapshotCount)
|
|
86
|
+
};
|
|
87
|
+
removeOldMemoryBufferRecords(end);
|
|
88
|
+
return memoryStateReport;
|
|
89
|
+
} catch (_unused2) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
50
93
|
export function initialisePressureObserver() {
|
|
51
94
|
try {
|
|
52
95
|
if ('PressureObserver' in globalThis) {
|
|
53
|
-
var _pressureObserver$obs;
|
|
54
96
|
pressureObserver = new PressureObserver(function (records) {
|
|
55
97
|
if (pressureRecordBuffer.length + records.length <= BUFFER_MAX_LENGTH) {
|
|
56
98
|
var _pressureRecordBuffer;
|
|
57
99
|
(_pressureRecordBuffer = pressureRecordBuffer).push.apply(_pressureRecordBuffer, _toConsumableArray(records));
|
|
58
100
|
}
|
|
59
101
|
});
|
|
60
|
-
|
|
102
|
+
pressureObserver.observe('cpu', {
|
|
61
103
|
sampleInterval: 100
|
|
62
|
-
})
|
|
104
|
+
}).catch();
|
|
63
105
|
}
|
|
64
106
|
} catch (err) {
|
|
65
107
|
/* do nothing, this is a best efforts metric */
|
|
66
108
|
}
|
|
67
109
|
}
|
|
110
|
+
export function initialiseMemoryObserver() {
|
|
111
|
+
try {
|
|
112
|
+
// only set up the interval if `performance.memory` is available in the browser
|
|
113
|
+
if ('memory' in performance) {
|
|
114
|
+
memoryInterval = setInterval(function () {
|
|
115
|
+
// another check of `performance.memory` availability to satisfy typescript
|
|
116
|
+
if ('memory' in performance) {
|
|
117
|
+
var memory = performance.memory;
|
|
118
|
+
if (memoryRecordBuffer.length <= BUFFER_MAX_LENGTH) {
|
|
119
|
+
memoryRecordBuffer.push({
|
|
120
|
+
time: performance.now(),
|
|
121
|
+
jsHeapSizeLimit: memory.jsHeapSizeLimit,
|
|
122
|
+
totalJSHeapSize: memory.totalJSHeapSize,
|
|
123
|
+
usedJSHeapSize: memory.usedJSHeapSize
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}, 100);
|
|
128
|
+
}
|
|
129
|
+
} catch (_unused3) {
|
|
130
|
+
/* do nothing, this is a best efforts metric */
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export function disconnectMemoryObserver() {
|
|
134
|
+
clearInterval(memoryInterval);
|
|
135
|
+
}
|
|
68
136
|
export function disconnectPressureObserver() {
|
|
69
137
|
var _pressureObserver;
|
|
70
138
|
(_pressureObserver = pressureObserver) === null || _pressureObserver === void 0 || _pressureObserver.disconnect();
|