@atlaskit/react-ufo 5.2.9 → 5.3.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 +16 -0
- package/dist/cjs/create-payload/index.js +6 -5
- package/dist/cjs/hidden-timing/index.js +52 -0
- package/dist/cjs/interaction-metrics/index.js +1 -0
- package/dist/cjs/interaction-metrics-init/index.js +2 -1
- package/dist/cjs/vc/index.js +4 -2
- package/dist/cjs/vc/vc-observer-new/index.js +10 -4
- package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +84 -29
- package/dist/cjs/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +164 -0
- package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +173 -34
- package/dist/cjs/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
- package/dist/cjs/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
- package/dist/es2019/create-payload/index.js +5 -3
- package/dist/es2019/hidden-timing/index.js +51 -0
- package/dist/es2019/interaction-metrics/index.js +1 -0
- package/dist/es2019/interaction-metrics-init/index.js +2 -1
- package/dist/es2019/vc/index.js +4 -2
- package/dist/es2019/vc/vc-observer-new/index.js +10 -5
- package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +61 -7
- package/dist/es2019/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +138 -0
- package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +145 -10
- package/dist/es2019/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
- package/dist/es2019/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
- package/dist/esm/create-payload/index.js +7 -6
- package/dist/esm/hidden-timing/index.js +51 -0
- package/dist/esm/interaction-metrics/index.js +1 -0
- package/dist/esm/interaction-metrics-init/index.js +2 -1
- package/dist/esm/vc/index.js +4 -2
- package/dist/esm/vc/vc-observer-new/index.js +10 -4
- package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +84 -29
- package/dist/esm/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +158 -0
- package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +173 -34
- package/dist/esm/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
- package/dist/esm/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
- package/dist/types/common/react-ufo-payload-schema.d.ts +2 -0
- package/dist/types/common/vc/types.d.ts +55 -0
- package/dist/types/config/index.d.ts +1 -0
- package/dist/types/hidden-timing/index.d.ts +9 -0
- package/dist/types/vc/types.d.ts +2 -0
- package/dist/types/vc/vc-observer-new/index.d.ts +2 -0
- package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
- package/dist/types/vc/vc-observer-new/metric-calculator/types.d.ts +1 -0
- package/dist/types/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.d.ts +31 -0
- package/dist/types/vc/vc-observer-new/types.d.ts +2 -0
- package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +3 -1
- package/dist/types/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +1 -0
- package/dist/types/vc/vc-observer-new/viewport-observer/types.d.ts +5 -2
- package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +2 -0
- package/dist/types-ts4.5/common/vc/types.d.ts +55 -0
- package/dist/types-ts4.5/config/index.d.ts +1 -0
- package/dist/types-ts4.5/hidden-timing/index.d.ts +9 -0
- package/dist/types-ts4.5/vc/types.d.ts +2 -0
- package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +2 -0
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/types.d.ts +1 -0
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.d.ts +31 -0
- package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +2 -0
- package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +3 -1
- package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +1 -0
- package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/types.d.ts +5 -2
- package/package.json +4 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.detectLayoutShiftCause = void 0;
|
|
7
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
8
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
9
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
10
|
+
var calculateOffenderState = function calculateOffenderState(current, matchesCurrentEntry) {
|
|
11
|
+
// Once we know it's mixed across entries, we can short-circuit.
|
|
12
|
+
if (current === 'some') {
|
|
13
|
+
return 'some';
|
|
14
|
+
}
|
|
15
|
+
var entryState = matchesCurrentEntry ? 'all' : 'none';
|
|
16
|
+
if (current == null) {
|
|
17
|
+
return entryState;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// If the state flips between entries (all <-> none), it's "some".
|
|
21
|
+
if (current !== entryState) {
|
|
22
|
+
return 'some';
|
|
23
|
+
}
|
|
24
|
+
return current;
|
|
25
|
+
};
|
|
26
|
+
var calculateLayoutShiftMovement = function calculateLayoutShiftMovement(layoutShiftEntries) {
|
|
27
|
+
var movements = layoutShiftEntries.map(function (lsEntry) {
|
|
28
|
+
var rect = lsEntry.rect;
|
|
29
|
+
var previousRect = lsEntry.previousRect;
|
|
30
|
+
if (!rect || !previousRect) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
var dx = rect.x - previousRect.x;
|
|
34
|
+
var dy = rect.y - previousRect.y;
|
|
35
|
+
return {
|
|
36
|
+
dx: dx,
|
|
37
|
+
dy: dy,
|
|
38
|
+
movedX: dx !== 0,
|
|
39
|
+
movedY: dy !== 0,
|
|
40
|
+
dirX: Math.sign(dx),
|
|
41
|
+
dirY: Math.sign(dy),
|
|
42
|
+
absDx: Math.abs(dx),
|
|
43
|
+
absDy: Math.abs(dy)
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
var hasMovement = function hasMovement(m) {
|
|
47
|
+
return m !== null;
|
|
48
|
+
};
|
|
49
|
+
var validMovements = movements.filter(hasMovement);
|
|
50
|
+
var allHaveRects = layoutShiftEntries.length > 0 && validMovements.length === layoutShiftEntries.length;
|
|
51
|
+
if (!allHaveRects) {
|
|
52
|
+
return {
|
|
53
|
+
allHaveRects: allHaveRects,
|
|
54
|
+
allMovedSameWay: false,
|
|
55
|
+
allMovedSameAmount: false
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
var first = validMovements[0];
|
|
59
|
+
var allMovedSameWay = validMovements.every(function (m) {
|
|
60
|
+
return m.movedX === first.movedX && m.movedY === first.movedY && m.dirX === first.dirX && m.dirY === first.dirY;
|
|
61
|
+
});
|
|
62
|
+
var allMovedSameAmount = allMovedSameWay && validMovements.every(function (m) {
|
|
63
|
+
return m.absDx === first.absDx && m.absDy === first.absDy;
|
|
64
|
+
});
|
|
65
|
+
return {
|
|
66
|
+
allHaveRects: allHaveRects,
|
|
67
|
+
allMovedSameWay: allMovedSameWay,
|
|
68
|
+
allMovedSameAmount: allMovedSameAmount,
|
|
69
|
+
deltaX: first.dx,
|
|
70
|
+
deltaY: first.dy
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
var detectLayoutShiftCause = exports.detectLayoutShiftCause = function detectLayoutShiftCause(_ref) {
|
|
74
|
+
var viewportEntries = _ref.viewportEntries,
|
|
75
|
+
layoutShiftEntries = _ref.layoutShiftEntries,
|
|
76
|
+
time = _ref.time,
|
|
77
|
+
startTime = _ref.startTime,
|
|
78
|
+
_ref$offenderWindowMs = _ref.offenderWindowMs,
|
|
79
|
+
offenderWindowMs = _ref$offenderWindowMs === void 0 ? 250 : _ref$offenderWindowMs;
|
|
80
|
+
var checkpointTimestamp = startTime + time;
|
|
81
|
+
var filteredLSPotentialOffenders = viewportEntries.filter(function (viewportEntry) {
|
|
82
|
+
return (viewportEntry.time < checkpointTimestamp && viewportEntry.time > checkpointTimestamp - offenderWindowMs || viewportEntry.time > checkpointTimestamp && viewportEntry.time < checkpointTimestamp + offenderWindowMs) && viewportEntry.data.type !== 'layout-shift';
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Summarize whether all layout-shift entries moved in a consistent direction and by the same amount.
|
|
86
|
+
var layoutShiftVariables = calculateLayoutShiftMovement(layoutShiftEntries);
|
|
87
|
+
|
|
88
|
+
// Classify each offender against *all* layout-shift entries when the layout shift is consistently moving in a
|
|
89
|
+
// single axis (pure X or pure Y) so we can reason about whether an offender could have caused the movement.
|
|
90
|
+
var layoutShiftOffenders = filteredLSPotentialOffenders.reduce(function (acc, offender) {
|
|
91
|
+
var _offenderData$origina;
|
|
92
|
+
var offenderData = offender.data;
|
|
93
|
+
var offenderRect = offenderData.rect;
|
|
94
|
+
if (!offenderRect) {
|
|
95
|
+
return acc;
|
|
96
|
+
}
|
|
97
|
+
var offenderTimestamp = (_offenderData$origina = offenderData.originalMutationTimestamp) !== null && _offenderData$origina !== void 0 ? _offenderData$origina : offender.time;
|
|
98
|
+
var happenedBefore = offenderTimestamp <= checkpointTimestamp;
|
|
99
|
+
var offenderLeft = offenderRect.x;
|
|
100
|
+
var offenderRight = offenderRect.x + offenderRect.width;
|
|
101
|
+
var offenderTop = offenderRect.y;
|
|
102
|
+
var offenderBottom = offenderRect.y + offenderRect.height;
|
|
103
|
+
var shouldClassifyAgainstAllEntries = layoutShiftVariables.allMovedSameWay && 'deltaX' in layoutShiftVariables && 'deltaY' in layoutShiftVariables && layoutShiftVariables.deltaX === 0 !== (layoutShiftVariables.deltaY === 0);
|
|
104
|
+
var isAbove = null;
|
|
105
|
+
var isLeft = null;
|
|
106
|
+
var isRight = null;
|
|
107
|
+
var hasHorizontalOverlap = null;
|
|
108
|
+
var hasVerticalOverlap = null;
|
|
109
|
+
if (shouldClassifyAgainstAllEntries) {
|
|
110
|
+
var _iterator = _createForOfIteratorHelper(layoutShiftEntries),
|
|
111
|
+
_step;
|
|
112
|
+
try {
|
|
113
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
114
|
+
var lsEntry = _step.value;
|
|
115
|
+
var lsRect = lsEntry.rect;
|
|
116
|
+
if (!lsRect) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
var lsLeft = lsRect.x;
|
|
120
|
+
var lsRight = lsRect.x + lsRect.width;
|
|
121
|
+
var lsTop = lsRect.y;
|
|
122
|
+
var lsBottom = lsRect.y + lsRect.height;
|
|
123
|
+
isAbove = calculateOffenderState(isAbove, offenderBottom <= lsTop);
|
|
124
|
+
isLeft = calculateOffenderState(isLeft, offenderRight <= lsLeft);
|
|
125
|
+
isRight = calculateOffenderState(isRight, offenderLeft >= lsRight);
|
|
126
|
+
hasHorizontalOverlap = calculateOffenderState(hasHorizontalOverlap, offenderLeft < lsRight && offenderRight > lsLeft);
|
|
127
|
+
hasVerticalOverlap = calculateOffenderState(hasVerticalOverlap, offenderTop < lsBottom && offenderBottom > lsTop);
|
|
128
|
+
}
|
|
129
|
+
} catch (err) {
|
|
130
|
+
_iterator.e(err);
|
|
131
|
+
} finally {
|
|
132
|
+
_iterator.f();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
var matchesLayoutShiftDelta = false;
|
|
136
|
+
if (shouldClassifyAgainstAllEntries && layoutShiftVariables.allMovedSameAmount && offenderData.previousRect) {
|
|
137
|
+
var dx = offenderRect.x - offenderData.previousRect.x;
|
|
138
|
+
var dy = offenderRect.y - offenderData.previousRect.y;
|
|
139
|
+
var isPureX = layoutShiftVariables.deltaX !== 0 && layoutShiftVariables.deltaY === 0;
|
|
140
|
+
var isPureY = layoutShiftVariables.deltaY !== 0 && layoutShiftVariables.deltaX === 0;
|
|
141
|
+
if (isPureX) {
|
|
142
|
+
matchesLayoutShiftDelta = dx === layoutShiftVariables.deltaX && dy === 0;
|
|
143
|
+
} else if (isPureY) {
|
|
144
|
+
matchesLayoutShiftDelta = dy === layoutShiftVariables.deltaY && dx === 0;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
acc.push({
|
|
148
|
+
offender: offenderData.elementName,
|
|
149
|
+
happenedBefore: happenedBefore,
|
|
150
|
+
distanceToLS: Math.round(offenderTimestamp - checkpointTimestamp),
|
|
151
|
+
isAbove: isAbove !== null && isAbove !== void 0 ? isAbove : 'none',
|
|
152
|
+
isLeft: isLeft !== null && isLeft !== void 0 ? isLeft : 'none',
|
|
153
|
+
isRight: isRight !== null && isRight !== void 0 ? isRight : 'none',
|
|
154
|
+
hasHorizontalOverlap: hasHorizontalOverlap !== null && hasHorizontalOverlap !== void 0 ? hasHorizontalOverlap : 'none',
|
|
155
|
+
hasVerticalOverlap: hasVerticalOverlap !== null && hasVerticalOverlap !== void 0 ? hasVerticalOverlap : 'none',
|
|
156
|
+
matchesLayoutShiftDelta: matchesLayoutShiftDelta
|
|
157
|
+
});
|
|
158
|
+
return acc;
|
|
159
|
+
}, []);
|
|
160
|
+
return {
|
|
161
|
+
layoutShiftVariables: layoutShiftVariables,
|
|
162
|
+
layoutShiftOffenders: layoutShiftOffenders
|
|
163
|
+
};
|
|
164
|
+
};
|
|
@@ -97,22 +97,151 @@ var createElementMutationsWatcher = function createElementMutationsWatcher(remov
|
|
|
97
97
|
return 'mutation:element';
|
|
98
98
|
};
|
|
99
99
|
};
|
|
100
|
+
var createElementMutationsWatcherNew = function createElementMutationsWatcherNew(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) {
|
|
101
|
+
return function (_ref2) {
|
|
102
|
+
var target = _ref2.target,
|
|
103
|
+
rect = _ref2.rect;
|
|
104
|
+
if (getSSRState) {
|
|
105
|
+
var ssrState = getSSRState();
|
|
106
|
+
var SSRStateEnum = {
|
|
107
|
+
normal: 1,
|
|
108
|
+
waitingForFirstRender: 2,
|
|
109
|
+
ignoring: 3
|
|
110
|
+
};
|
|
111
|
+
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && isTargetReactRoot) {
|
|
112
|
+
ssrState.state = SSRStateEnum.ignoring;
|
|
113
|
+
if (ssrState.renderStop === -1) {
|
|
114
|
+
// arbitrary 500ms DOM update window
|
|
115
|
+
ssrState.renderStop = timestamp + 500;
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
type: 'ssr-hydration',
|
|
119
|
+
mutationData: {
|
|
120
|
+
timestamp: timestamp
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && isTargetReactRoot) {
|
|
125
|
+
if (timestamp <= ssrState.renderStop) {
|
|
126
|
+
return {
|
|
127
|
+
type: 'ssr-hydration',
|
|
128
|
+
mutationData: {
|
|
129
|
+
timestamp: timestamp
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
} else {
|
|
133
|
+
ssrState.state = SSRStateEnum.normal;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (getSSRPlaceholderHandler) {
|
|
138
|
+
var ssrPlaceholderHandler = getSSRPlaceholderHandler();
|
|
139
|
+
if (ssrPlaceholderHandler) {
|
|
140
|
+
if ((ssrPlaceholderHandler.isPlaceholderV4(target) || ssrPlaceholderHandler.isPlaceholderIgnored(target)) && ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(target)) {
|
|
141
|
+
return {
|
|
142
|
+
type: 'mutation:ssr-placeholder',
|
|
143
|
+
mutationData: {
|
|
144
|
+
timestamp: timestamp
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
if ((ssrPlaceholderHandler.isPlaceholderReplacementV4(target) || ssrPlaceholderHandler.isPlaceholderIgnored(target)) && ssrPlaceholderHandler.validateReactComponentMatchToPlaceholderV4(target)) {
|
|
149
|
+
return {
|
|
150
|
+
type: 'mutation:ssr-placeholder',
|
|
151
|
+
mutationData: {
|
|
152
|
+
timestamp: timestamp
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (hasSameDeletedNode && (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(target)) {
|
|
159
|
+
return {
|
|
160
|
+
type: 'mutation:remount',
|
|
161
|
+
mutationData: {
|
|
162
|
+
timestamp: timestamp
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if ((0, _vcUtils.isContainedWithinMediaWrapper)(target)) {
|
|
167
|
+
return {
|
|
168
|
+
type: 'mutation:media',
|
|
169
|
+
mutationData: {
|
|
170
|
+
timestamp: timestamp
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (isWithinThirdPartySegment) {
|
|
175
|
+
return {
|
|
176
|
+
type: 'mutation:third-party-element',
|
|
177
|
+
mutationData: {
|
|
178
|
+
timestamp: timestamp
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
if (isWithinSmartAnswersSegment) {
|
|
183
|
+
return {
|
|
184
|
+
type: 'mutation:smart-answers-element',
|
|
185
|
+
mutationData: {
|
|
186
|
+
timestamp: timestamp
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
var isInIgnoreLsMarker = (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(target);
|
|
191
|
+
if (!isInIgnoreLsMarker) {
|
|
192
|
+
return {
|
|
193
|
+
type: 'mutation:element',
|
|
194
|
+
mutationData: {
|
|
195
|
+
timestamp: timestamp
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
var isRLLPlaceholder = _rllPlaceholders.RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
|
|
200
|
+
if (isRLLPlaceholder && isInIgnoreLsMarker) {
|
|
201
|
+
return {
|
|
202
|
+
type: 'mutation:rll-placeholder',
|
|
203
|
+
mutationData: {
|
|
204
|
+
timestamp: timestamp
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
var wasDeleted = removedNodeRects.some(function (nr) {
|
|
209
|
+
return (0, _isSameRectDimensions.isSameRectDimensions)(nr, rect);
|
|
210
|
+
});
|
|
211
|
+
if (wasDeleted && isInIgnoreLsMarker) {
|
|
212
|
+
return {
|
|
213
|
+
type: 'mutation:element-replacement',
|
|
214
|
+
mutationData: {
|
|
215
|
+
timestamp: timestamp
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
type: 'mutation:element',
|
|
221
|
+
mutationData: {
|
|
222
|
+
timestamp: timestamp
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
};
|
|
100
227
|
var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
101
228
|
// SSR context functions
|
|
102
229
|
|
|
103
|
-
function ViewportObserver(
|
|
230
|
+
function ViewportObserver(_ref3) {
|
|
104
231
|
var _this = this;
|
|
105
|
-
var onChange =
|
|
106
|
-
getSSRState =
|
|
107
|
-
getSSRPlaceholderHandler =
|
|
108
|
-
|
|
232
|
+
var onChange = _ref3.onChange,
|
|
233
|
+
getSSRState = _ref3.getSSRState,
|
|
234
|
+
getSSRPlaceholderHandler = _ref3.getSSRPlaceholderHandler,
|
|
235
|
+
_ref3$trackLayoutShif = _ref3.trackLayoutShiftOffenders,
|
|
236
|
+
trackLayoutShiftOffenders = _ref3$trackLayoutShif === void 0 ? false : _ref3$trackLayoutShif,
|
|
237
|
+
searchPageConfig = _ref3.searchPageConfig;
|
|
109
238
|
(0, _classCallCheck2.default)(this, ViewportObserver);
|
|
110
|
-
(0, _defineProperty2.default)(this, "handleIntersectionEntry", function (
|
|
111
|
-
var target =
|
|
112
|
-
rect =
|
|
113
|
-
time =
|
|
114
|
-
type =
|
|
115
|
-
mutationData =
|
|
239
|
+
(0, _defineProperty2.default)(this, "handleIntersectionEntry", function (_ref4) {
|
|
240
|
+
var target = _ref4.target,
|
|
241
|
+
rect = _ref4.rect,
|
|
242
|
+
time = _ref4.time,
|
|
243
|
+
type = _ref4.type,
|
|
244
|
+
mutationData = _ref4.mutationData;
|
|
116
245
|
if (!target) {
|
|
117
246
|
return;
|
|
118
247
|
}
|
|
@@ -130,12 +259,12 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
130
259
|
});
|
|
131
260
|
});
|
|
132
261
|
(0, _defineProperty2.default)(this, "handleChildListMutation", /*#__PURE__*/function () {
|
|
133
|
-
var
|
|
262
|
+
var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref5) {
|
|
134
263
|
var target, addedNodes, removedNodes, timestamp, removedNodeRects, targetNode, _iterator, _step, _loop;
|
|
135
264
|
return _regenerator.default.wrap(function _callee$(_context2) {
|
|
136
265
|
while (1) switch (_context2.prev = _context2.next) {
|
|
137
266
|
case 0:
|
|
138
|
-
target =
|
|
267
|
+
target = _ref5.target, addedNodes = _ref5.addedNodes, removedNodes = _ref5.removedNodes, timestamp = _ref5.timestamp;
|
|
139
268
|
removedNodeRects = removedNodes.map(function (ref) {
|
|
140
269
|
var n = ref.deref();
|
|
141
270
|
if (!n) {
|
|
@@ -170,7 +299,7 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
170
299
|
_checkWithinComponent = (0, _checkWithinComponent3.default)(addedNode, 'UFOThirdPartySegment', _this.mapIs3pResult), isWithinThirdPartySegment = _checkWithinComponent.isWithin;
|
|
171
300
|
isWithinSmartAnswersSegment = Boolean(_this.shouldCheckSmartAnswersMutations() && (0, _isContainedWithinSmartAnswers.isContainedWithinSmartAnswers)(addedNode));
|
|
172
301
|
isTargetReactRoot = targetNode === ((_this$getSSRState = _this.getSSRState) === null || _this$getSSRState === void 0 || (_this$getSSRState = _this$getSSRState.call(_this)) === null || _this$getSSRState === void 0 ? void 0 : _this$getSSRState.reactRootElement);
|
|
173
|
-
(_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
|
|
302
|
+
(_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, (_this.trackLayoutShiftOffenders ? createElementMutationsWatcherNew : createElementMutationsWatcher)(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
|
|
174
303
|
case 9:
|
|
175
304
|
case "end":
|
|
176
305
|
return _context.stop();
|
|
@@ -211,25 +340,27 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
211
340
|
}, _callee, null, [[4, 15, 18, 21]]);
|
|
212
341
|
}));
|
|
213
342
|
return function (_x) {
|
|
214
|
-
return
|
|
343
|
+
return _ref6.apply(this, arguments);
|
|
215
344
|
};
|
|
216
345
|
}());
|
|
217
|
-
(0, _defineProperty2.default)(this, "handleAttributeMutation", function (
|
|
346
|
+
(0, _defineProperty2.default)(this, "handleAttributeMutation", function (_ref7) {
|
|
218
347
|
var _this$intersectionObs2;
|
|
219
|
-
var target =
|
|
220
|
-
attributeName =
|
|
221
|
-
oldValue =
|
|
222
|
-
newValue =
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
348
|
+
var target = _ref7.target,
|
|
349
|
+
attributeName = _ref7.attributeName,
|
|
350
|
+
oldValue = _ref7.oldValue,
|
|
351
|
+
newValue = _ref7.newValue,
|
|
352
|
+
timestamp = _ref7.timestamp;
|
|
353
|
+
(_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(target, function (_ref8) {
|
|
354
|
+
var target = _ref8.target,
|
|
355
|
+
rect = _ref8.rect;
|
|
226
356
|
if ((0, _vcUtils.isContainedWithinMediaWrapper)(target)) {
|
|
227
357
|
return {
|
|
228
358
|
type: 'mutation:media',
|
|
229
359
|
mutationData: {
|
|
230
360
|
attributeName: attributeName,
|
|
231
361
|
oldValue: oldValue,
|
|
232
|
-
newValue: newValue
|
|
362
|
+
newValue: newValue,
|
|
363
|
+
timestamp: timestamp
|
|
233
364
|
}
|
|
234
365
|
};
|
|
235
366
|
}
|
|
@@ -242,7 +373,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
242
373
|
mutationData: {
|
|
243
374
|
attributeName: attributeName,
|
|
244
375
|
oldValue: oldValue,
|
|
245
|
-
newValue: newValue
|
|
376
|
+
newValue: newValue,
|
|
377
|
+
timestamp: timestamp
|
|
246
378
|
}
|
|
247
379
|
};
|
|
248
380
|
}
|
|
@@ -268,7 +400,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
268
400
|
mutationData: {
|
|
269
401
|
attributeName: attributeName,
|
|
270
402
|
oldValue: oldValue,
|
|
271
|
-
newValue: newValue
|
|
403
|
+
newValue: newValue,
|
|
404
|
+
timestamp: timestamp
|
|
272
405
|
}
|
|
273
406
|
};
|
|
274
407
|
}
|
|
@@ -282,7 +415,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
282
415
|
mutationData: {
|
|
283
416
|
attributeName: attributeName,
|
|
284
417
|
oldValue: oldValue,
|
|
285
|
-
newValue: newValue
|
|
418
|
+
newValue: newValue,
|
|
419
|
+
timestamp: timestamp
|
|
286
420
|
}
|
|
287
421
|
};
|
|
288
422
|
}
|
|
@@ -297,7 +431,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
297
431
|
mutationData: {
|
|
298
432
|
attributeName: attributeName,
|
|
299
433
|
oldValue: oldValue,
|
|
300
|
-
newValue: newValue
|
|
434
|
+
newValue: newValue,
|
|
435
|
+
timestamp: timestamp
|
|
301
436
|
}
|
|
302
437
|
};
|
|
303
438
|
}
|
|
@@ -308,7 +443,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
308
443
|
mutationData: {
|
|
309
444
|
attributeName: attributeName,
|
|
310
445
|
oldValue: oldValue,
|
|
311
|
-
newValue: newValue
|
|
446
|
+
newValue: newValue,
|
|
447
|
+
timestamp: timestamp
|
|
312
448
|
}
|
|
313
449
|
};
|
|
314
450
|
}
|
|
@@ -319,7 +455,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
319
455
|
mutationData: {
|
|
320
456
|
attributeName: attributeName,
|
|
321
457
|
oldValue: oldValue,
|
|
322
|
-
newValue: newValue
|
|
458
|
+
newValue: newValue,
|
|
459
|
+
timestamp: timestamp
|
|
323
460
|
}
|
|
324
461
|
};
|
|
325
462
|
}
|
|
@@ -328,14 +465,15 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
328
465
|
mutationData: {
|
|
329
466
|
attributeName: attributeName,
|
|
330
467
|
oldValue: oldValue,
|
|
331
|
-
newValue: newValue
|
|
468
|
+
newValue: newValue,
|
|
469
|
+
timestamp: timestamp
|
|
332
470
|
}
|
|
333
471
|
};
|
|
334
472
|
});
|
|
335
473
|
});
|
|
336
|
-
(0, _defineProperty2.default)(this, "handleLayoutShift", function (
|
|
337
|
-
var time =
|
|
338
|
-
changedRects =
|
|
474
|
+
(0, _defineProperty2.default)(this, "handleLayoutShift", function (_ref9) {
|
|
475
|
+
var time = _ref9.time,
|
|
476
|
+
changedRects = _ref9.changedRects;
|
|
339
477
|
var _iterator2 = _createForOfIteratorHelper(changedRects),
|
|
340
478
|
_step2;
|
|
341
479
|
try {
|
|
@@ -371,6 +509,7 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
|
|
|
371
509
|
this.intersectionObserver = null;
|
|
372
510
|
this.mutationObserver = null;
|
|
373
511
|
this.performanceObserver = null;
|
|
512
|
+
this.trackLayoutShiftOffenders = trackLayoutShiftOffenders;
|
|
374
513
|
|
|
375
514
|
// Initialize SSR context functions
|
|
376
515
|
this.getSSRState = getSSRState;
|
|
@@ -36,7 +36,7 @@ function createIntersectionObserver(_ref) {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
// override as display-contents mutation
|
|
39
|
-
if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute') {
|
|
39
|
+
if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute' && 'oldValue' in tagOrCallbackResult.mutationData) {
|
|
40
40
|
var _tagOrCallbackResult$ = tagOrCallbackResult.mutationData,
|
|
41
41
|
attributeName = _tagOrCallbackResult$.attributeName,
|
|
42
42
|
oldValue = _tagOrCallbackResult$.oldValue,
|
|
@@ -58,7 +58,8 @@ function createMutationObserver(_ref) {
|
|
|
58
58
|
target: mut.target,
|
|
59
59
|
attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
|
|
60
60
|
oldValue: oldValue,
|
|
61
|
-
newValue: newValue
|
|
61
|
+
newValue: newValue,
|
|
62
|
+
timestamp: mut.timestamp || performance.now()
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
65
|
return 0; // continue
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{getDocument}from'@atlaskit/browser-apis';import{fg}from'@atlaskit/platform-feature-flags';// Import common utilities
|
|
2
|
-
import{getLighthouseMetrics}from'../additional-payload';import{CHRReporter}from'../assets';import*as bundleEvalTiming from'../bundle-eval-timing';import coinflip from'../coinflip';import{getConfig,getExperimentalInteractionRate,getUfoNameOverrides,shouldUseRawDataThirdPartyBehavior}from'../config';import{getExperimentalVCMetrics}from'../create-experimental-interaction-metrics-payload';import{getBm3Timings}from'../custom-timings';import{getGlobalErrorCount}from'../global-error-handler';import{getEarliestHiddenTiming,getHasHiddenTimingBeforeSetup,getPageVisibilityState,isOpenedInBackground,isTabThrottled}from'../hidden-timing';import*as initialPageLoadExtraTiming from'../initial-page-load-extra-timing';import{interactionSpans as atlaskitInteractionSpans}from'../interaction-metrics';import{createMemoryStateReport,createPressureStateReport}from'../machine-utilisation';import*as resourceTiming from'../resource-timing';import{filterResourceTimings}from'../resource-timing/common/utils/resource-timing-buffer';import{roundEpsilon}from'../round-number';import*as ssr from'../ssr';import{getHasAbortingEventDuringSSR}from'../vc/vc-observer-new';import{buildSegmentTree,getOldSegmentsLabelStack,labelStackStartWith,optimizeLabelStack,sanitizeUfoName,stringifyLabelStackFully}from'./common/utils';import{createCriticalMetricsPayloads}from'./critical-metrics-payload';import{addPerformanceMeasures}from'./utils/add-performance-measures';import{getBatteryInfoToLegacyFormat}from'./utils/get-battery-info';import{getBrowserMetadataToLegacyFormat}from'./utils/get-browser-metadata';import getInteractionStatus from'./utils/get-interaction-status';import{getMoreAccuratePageVisibilityUpToTTAI}from'./utils/get-more-accurate-page-visibility-up-to-ttai';import{getNavigationMetricsToLegacyFormat}from'./utils/get-navigation-metrics';import getPageVisibilityUpToTTAI from'./utils/get-page-visibility-up-to-ttai';import{getPaintMetricsToLegacyFormat}from'./utils/get-paint-metrics';import getPayloadSize from'./utils/get-payload-size';import{getReactUFOPayloadVersion}from'./utils/get-react-ufo-payload-version';import getSSRDoneTimeValue from'./utils/get-ssr-done-time-value';import getSSRSuccessUtil from'./utils/get-ssr-success';import getTTAI from'./utils/get-ttai';import getVCMetrics from'./utils/get-vc-metrics';import{getVisibilityStateFromPerformance}from'./utils/get-visibility-state-from-performance';import{optimizeApdex}from'./utils/optimize-apdex';import{optimizeCustomTimings}from'./utils/optimize-custom-timings';import{optimizeHoldInfo}from'./utils/optimize-hold-info';import{optimizeMarks}from'./utils/optimize-marks';import{optimizeReactProfilerTimings}from'./utils/optimize-react-profiler-timings';import{optimizeRequestInfo}from'./utils/optimize-request-info';import{optimizeSpans}from'./utils/optimize-spans';import{trimVcDebugData}from'./utils/trim-vc-debug-data';const MAX_PAYLOAD_SIZE=230;function getUfoNameOverride(interaction){const{ufoName,apdex}=interaction;try{const ufoNameOverrides=getUfoNameOverrides();if(ufoNameOverrides!=null){const metricKey=apdex.length>0?apdex[0].key:'';if(ufoNameOverrides[ufoName][metricKey]){return ufoNameOverrides[ufoName][metricKey];}}return ufoName;}catch{return ufoName;}}function getEarliestLegacyStopTime(interaction,labelStack){let earliestLegacyStopTime=null;interaction.apdex.forEach(a=>{var _a$labelStack,_earliestLegacyStopTi;if(!(a!==null&&a!==void 0&&a.stopTime)){return;}if(!labelStackStartWith((_a$labelStack=a.labelStack)!==null&&_a$labelStack!==void 0?_a$labelStack:[],labelStack)){return;}if(a.stopTime>interaction.start&&((_earliestLegacyStopTi=earliestLegacyStopTime)!==null&&_earliestLegacyStopTi!==void 0?_earliestLegacyStopTi:a.stopTime)>=a.stopTime){earliestLegacyStopTime=a.stopTime;}});return earliestLegacyStopTime;}function getBm3EndTimeOrFallbackValue(interaction,labelStack=[],fallbackValue=interaction.end){var _getEarliestLegacySto;if(interaction.type==='press'){return fallbackValue;}return(_getEarliestLegacySto=getEarliestLegacyStopTime(interaction,labelStack))!==null&&_getEarliestLegacySto!==void 0?_getEarliestLegacySto:fallbackValue;}function getPageVisibilityUpToTTI(interaction){const{start}=interaction;const bm3EndTimeOrInteractionEndTime=getBm3EndTimeOrFallbackValue(interaction);return getPageVisibilityState(start,bm3EndTimeOrInteractionEndTime);}function getMoreAccuratePageVisibilityUpToTTI(interaction){const old=getPageVisibilityUpToTTI(interaction);const tti=getEarliestLegacyStopTime(interaction,[]);if(!tti){return old;}const buffered=getVisibilityStateFromPerformance(tti);if(!buffered){return old;}if(buffered!==old){return'mixed';}return old;}function getResourceTimings(start,end){var _resourceTiming$getRe;return(_resourceTiming$getRe=resourceTiming.getResourceTimings(start,end))!==null&&_resourceTiming$getRe!==void 0?_resourceTiming$getRe:undefined;}function getBundleEvalTimings(start){return bundleEvalTiming.getBundleEvalTimings(start);}function getSSRPhaseSuccess(type){return type==='page_load'?ssr.getSSRPhaseSuccess():undefined;}function getSSRFeatureFlags(type){return type==='page_load'?ssr.getSSRFeatureFlags():undefined;}function getPPSMetrics(interaction){var _interaction$apdex,_interaction$apdex$;const{start,end}=interaction;const config=getConfig();const interactionStatus=getInteractionStatus(interaction);const pageVisibilityUpToTTAI=getPageVisibilityUpToTTAI(interaction);const tti=(_interaction$apdex=interaction.apdex)===null||_interaction$apdex===void 0?void 0:(_interaction$apdex$=_interaction$apdex[0])===null||_interaction$apdex$===void 0?void 0:_interaction$apdex$.stopTime;const ttai=interactionStatus.originalInteractionStatus==='SUCCEEDED'&&pageVisibilityUpToTTAI==='visible'?Math.round(end-start):undefined;const PPSMetricsAtTTI=tti!==undefined?getLighthouseMetrics({start,stop:tti}):null;const PPSMetricsAtTTAI=ttai!==undefined?getLighthouseMetrics({start,stop:interaction.end}):null;if(fg('platform_ufo_remove_deprecated_config_fields')){if(PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}}else{if(config!==null&&config!==void 0&&config.shouldCalculateLighthouseMetricsFromTTAI&&PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}if(PPSMetricsAtTTI!==null){return{...PPSMetricsAtTTI,'metrics@ttai':PPSMetricsAtTTAI};}}return{};}function getSSRProperties(type){const ssrPhases=getSSRPhaseSuccess(type);return{'ssr:success':(ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.done)!=null?ssrPhases.done:getSSRSuccessUtil(type),'ssr:featureFlags':getSSRFeatureFlags(type),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.earlyFlush)!=null?{'ssr:earlyflush:success':ssrPhases.earlyFlush}:null),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.prefetch)!=null?{'ssr:prefetch:success':ssrPhases.prefetch}:null)};}function getAssetsMetrics(interaction,SSRDoneTime){try{const config=getConfig();const{type}=interaction;const allowedTypes=['page_load'];const assetsConfig=config===null||config===void 0?void 0:config.assetsConfig;if(!allowedTypes.includes(type)||!assetsConfig){// Skip if: type not allowed or assetsClassification isn't configured
|
|
2
|
+
import{getLighthouseMetrics}from'../additional-payload';import{CHRReporter}from'../assets';import*as bundleEvalTiming from'../bundle-eval-timing';import coinflip from'../coinflip';import{getConfig,getExperimentalInteractionRate,getUfoNameOverrides,shouldUseRawDataThirdPartyBehavior}from'../config';import{getExperimentalVCMetrics}from'../create-experimental-interaction-metrics-payload';import{getBm3Timings}from'../custom-timings';import{getGlobalErrorCount}from'../global-error-handler';import{getEarliestHiddenTiming,getHasHiddenTimingBeforeSetup,getPageVisibilityState,getPageVisibilityTimeline,isOpenedInBackground,isTabThrottled}from'../hidden-timing';import*as initialPageLoadExtraTiming from'../initial-page-load-extra-timing';import{interactionSpans as atlaskitInteractionSpans}from'../interaction-metrics';import{createMemoryStateReport,createPressureStateReport}from'../machine-utilisation';import*as resourceTiming from'../resource-timing';import{filterResourceTimings}from'../resource-timing/common/utils/resource-timing-buffer';import{roundEpsilon}from'../round-number';import*as ssr from'../ssr';import{getHasAbortingEventDuringSSR}from'../vc/vc-observer-new';import{buildSegmentTree,getOldSegmentsLabelStack,labelStackStartWith,optimizeLabelStack,sanitizeUfoName,stringifyLabelStackFully}from'./common/utils';import{createCriticalMetricsPayloads}from'./critical-metrics-payload';import{addPerformanceMeasures}from'./utils/add-performance-measures';import{getBatteryInfoToLegacyFormat}from'./utils/get-battery-info';import{getBrowserMetadataToLegacyFormat}from'./utils/get-browser-metadata';import getInteractionStatus from'./utils/get-interaction-status';import{getMoreAccuratePageVisibilityUpToTTAI}from'./utils/get-more-accurate-page-visibility-up-to-ttai';import{getNavigationMetricsToLegacyFormat}from'./utils/get-navigation-metrics';import getPageVisibilityUpToTTAI from'./utils/get-page-visibility-up-to-ttai';import{getPaintMetricsToLegacyFormat}from'./utils/get-paint-metrics';import getPayloadSize from'./utils/get-payload-size';import{getReactUFOPayloadVersion}from'./utils/get-react-ufo-payload-version';import getSSRDoneTimeValue from'./utils/get-ssr-done-time-value';import getSSRSuccessUtil from'./utils/get-ssr-success';import getTTAI from'./utils/get-ttai';import getVCMetrics from'./utils/get-vc-metrics';import{getVisibilityStateFromPerformance}from'./utils/get-visibility-state-from-performance';import{optimizeApdex}from'./utils/optimize-apdex';import{optimizeCustomTimings}from'./utils/optimize-custom-timings';import{optimizeHoldInfo}from'./utils/optimize-hold-info';import{optimizeMarks}from'./utils/optimize-marks';import{optimizeReactProfilerTimings}from'./utils/optimize-react-profiler-timings';import{optimizeRequestInfo}from'./utils/optimize-request-info';import{optimizeSpans}from'./utils/optimize-spans';import{trimVcDebugData}from'./utils/trim-vc-debug-data';const MAX_PAYLOAD_SIZE=230;function getUfoNameOverride(interaction){const{ufoName,apdex}=interaction;try{const ufoNameOverrides=getUfoNameOverrides();if(ufoNameOverrides!=null){const metricKey=apdex.length>0?apdex[0].key:'';if(ufoNameOverrides[ufoName][metricKey]){return ufoNameOverrides[ufoName][metricKey];}}return ufoName;}catch{return ufoName;}}function getEarliestLegacyStopTime(interaction,labelStack){let earliestLegacyStopTime=null;interaction.apdex.forEach(a=>{var _a$labelStack,_earliestLegacyStopTi;if(!(a!==null&&a!==void 0&&a.stopTime)){return;}if(!labelStackStartWith((_a$labelStack=a.labelStack)!==null&&_a$labelStack!==void 0?_a$labelStack:[],labelStack)){return;}if(a.stopTime>interaction.start&&((_earliestLegacyStopTi=earliestLegacyStopTime)!==null&&_earliestLegacyStopTi!==void 0?_earliestLegacyStopTi:a.stopTime)>=a.stopTime){earliestLegacyStopTime=a.stopTime;}});return earliestLegacyStopTime;}function getBm3EndTimeOrFallbackValue(interaction,labelStack=[],fallbackValue=interaction.end){var _getEarliestLegacySto;if(interaction.type==='press'){return fallbackValue;}return(_getEarliestLegacySto=getEarliestLegacyStopTime(interaction,labelStack))!==null&&_getEarliestLegacySto!==void 0?_getEarliestLegacySto:fallbackValue;}function getPageVisibilityUpToTTI(interaction){const{start}=interaction;const bm3EndTimeOrInteractionEndTime=getBm3EndTimeOrFallbackValue(interaction);return getPageVisibilityState(start,bm3EndTimeOrInteractionEndTime);}function getMoreAccuratePageVisibilityUpToTTI(interaction){const old=getPageVisibilityUpToTTI(interaction);const tti=getEarliestLegacyStopTime(interaction,[]);if(!tti){return old;}const buffered=getVisibilityStateFromPerformance(tti);if(!buffered){return old;}if(buffered!==old){return'mixed';}return old;}function getResourceTimings(start,end){var _resourceTiming$getRe;return(_resourceTiming$getRe=resourceTiming.getResourceTimings(start,end))!==null&&_resourceTiming$getRe!==void 0?_resourceTiming$getRe:undefined;}function getBundleEvalTimings(start){return bundleEvalTiming.getBundleEvalTimings(start);}function getSSRPhaseSuccess(type){return type==='page_load'?ssr.getSSRPhaseSuccess():undefined;}function getSSRFeatureFlags(type){return type==='page_load'?ssr.getSSRFeatureFlags():undefined;}function getPPSMetrics(interaction){var _interaction$apdex,_interaction$apdex$;const{start,end}=interaction;const config=getConfig();const interactionStatus=getInteractionStatus(interaction);const pageVisibilityUpToTTAI=getPageVisibilityUpToTTAI(interaction);const tti=(_interaction$apdex=interaction.apdex)===null||_interaction$apdex===void 0?void 0:(_interaction$apdex$=_interaction$apdex[0])===null||_interaction$apdex$===void 0?void 0:_interaction$apdex$.stopTime;const ttai=interactionStatus.originalInteractionStatus==='SUCCEEDED'&&pageVisibilityUpToTTAI==='visible'?Math.round(end-start):undefined;const PPSMetricsAtTTI=tti!==undefined?getLighthouseMetrics({start,stop:tti}):null;const PPSMetricsAtTTAI=ttai!==undefined?getLighthouseMetrics({start,stop:interaction.end}):null;if(fg('platform_ufo_remove_deprecated_config_fields')){if(PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}}else{if(config!==null&&config!==void 0&&config.shouldCalculateLighthouseMetricsFromTTAI&&PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}if(PPSMetricsAtTTI!==null){return{...PPSMetricsAtTTI,'metrics@ttai':PPSMetricsAtTTAI};}}return{};}function getSSRProperties(type){const ssrPhases=getSSRPhaseSuccess(type);return{'ssr:success':(ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.done)!=null?ssrPhases.done:getSSRSuccessUtil(type),'ssr:featureFlags':getSSRFeatureFlags(type),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.earlyFlush)!=null?{'ssr:earlyflush:success':ssrPhases.earlyFlush}:null),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.prefetch)!=null?{'ssr:prefetch:success':ssrPhases.prefetch}:null)};}function getAssetsMetrics(interaction,SSRDoneTime){try{const config=getConfig();const{type}=interaction;const allowedTypes=['page_load'];const assetsConfig=config===null||config===void 0?void 0:config.assetsConfig;if(!allowedTypes.includes(type)||!assetsConfig){// Skip if: type not allowed or assetsClassification isn't configured
|
|
3
3
|
return{};}const reporter=new CHRReporter();const resourceTimings=filterResourceTimings(interaction.start,interaction.end);const assets=reporter.get(resourceTimings,assetsConfig,SSRDoneTime);if(assets){// Only add assets in case it exists
|
|
4
4
|
return{'event:assets':assets};}return{};}catch{// Skip CHR in case of error
|
|
5
5
|
return{};}}function getTracingContextData(interaction){const{trace,start}=interaction;let tracingContextData={};if(trace){tracingContextData={'ufo:tracingContext':{'X-B3-TraceId':trace.traceId,'X-B3-SpanId':trace.spanId,// eslint-disable-next-line compat/compat
|
|
@@ -11,12 +11,14 @@ const getDetailedInteractionMetrics=resourceTimings=>{if(experimental||window.__
|
|
|
11
11
|
if(shouldInclude3pHolds){var _interaction$hold3pIn;return{...basePayload,hold3pActive:interaction.hold3pActive?[...interaction.hold3pActive.values()]:[],hold3pInfo:optimizeHoldInfo((_interaction$hold3pIn=interaction.hold3pInfo)!==null&&_interaction$hold3pIn!==void 0?_interaction$hold3pIn:[],start,getReactUFOPayloadVersion(interaction.type))};}return basePayload;};// Page load & detailed payload
|
|
12
12
|
const getPageLoadDetailedInteractionMetrics=()=>{var _config$ssr2,_config$ssr2$getSSRTi;if(!isPageLoad||!isDetailedPayload){return{};}const initialPageLoadExtraTimings=objectToArray(initialPageLoadExtraTiming.getTimings());const config=getConfig();const defaultSSRTimings=objectToArray(ssr.getSSRTimings());const ssrTimingsFromConfig=config===null||config===void 0?void 0:(_config$ssr2=config.ssr)===null||_config$ssr2===void 0?void 0:(_config$ssr2$getSSRTi=_config$ssr2.getSSRTimings)===null||_config$ssr2$getSSRTi===void 0?void 0:_config$ssr2$getSSRTi.call(_config$ssr2);return{initialPageLoadExtraTimings,SSRTimings:ssrTimingsFromConfig?[...ssrTimingsFromConfig,...defaultSSRTimings]:defaultSSRTimings};};if(experimental){expTTAI=getTTAI(interaction);}else{regularTTAI=getTTAI(interaction);}const newUFOName=sanitizeUfoName(ufoName);const resourceTimings=getResourceTimings(start,end);const[finalVCMetrics,experimentalMetrics,paintMetrics,batteryInfo]=await Promise.all([vcMetrics||(await getVCMetrics(interaction)),experimental?getExperimentalVCMetrics(interaction):Promise.resolve(undefined),getPaintMetricsToLegacyFormat(type,end),getBatteryInfoToLegacyFormat()]);if(!experimental){addPerformanceMeasures(interaction.start,[...((finalVCMetrics===null||finalVCMetrics===void 0?void 0:finalVCMetrics['ufo:vc:rev'])||[])]);}const getReactHydrationStats=()=>{if(!hydration){return{};}return{hydration};};const payload={actionSubject:'experience',action:'measured',eventType:'operational',source:'measured',tags:['observability'],attributes:{properties:{// basic
|
|
13
13
|
'event:hostname':((_window$location=window.location)===null||_window$location===void 0?void 0:_window$location.hostname)||'unknown','event:product':config.product,'event:population':config.population,'event:schema':'1.0.0','event:sizeInKb':0,'event:source':{name:'react-ufo/web',version:getReactUFOPayloadVersion(interaction.type)},'event:region':config.region||'unknown','experience:key':experimental?'custom.experimental-interaction-metrics':'custom.interaction-metrics','experience:name':newUFOName,// Include CPU usage monitoring data
|
|
14
|
-
'event:cpu:usage':createPressureStateReport(interaction.start,interaction.end),'event:memory:usage':createMemoryStateReport(interaction.start,interaction.end),...(criticalPayloadCount!==undefined?{'ufo:multipayload':true,'ufo:criticalPayloadCount':criticalPayloadCount}:{}),'ufo:pageVisibilityHiddenTimestamp':getEarliestHiddenTiming(interaction.start,interaction.end),'ufo:wasPageHiddenBeforeInit':getHasHiddenTimingBeforeSetup(),'ufo:isOpenedInBackground':isOpenedInBackground(interaction.type),'ufo:isTabThrottled':isTabThrottled(start,end),...(fg('ufo_detect_aborting_interaction_during_ssr')?{'ufo:hasAbortingInteractionDuringSSR':getHasAbortingEventDuringSSR()}:{}),// root
|
|
14
|
+
'event:cpu:usage':createPressureStateReport(interaction.start,interaction.end),'event:memory:usage':createMemoryStateReport(interaction.start,interaction.end),...(criticalPayloadCount!==undefined?{'ufo:multipayload':true,'ufo:criticalPayloadCount':criticalPayloadCount}:{}),'ufo:pageVisibilityHiddenTimestamp':getEarliestHiddenTiming(interaction.start,interaction.end),'ufo:wasPageHiddenBeforeInit':getHasHiddenTimingBeforeSetup(),'ufo:isOpenedInBackground':isOpenedInBackground(interaction.type),'ufo:isTabThrottled':isTabThrottled(start,end),...(fg('platform_ufo_page_visibility_timeline')?{'ufo:pageVisibilityTimeline':getPageVisibilityTimeline(start,end)}:{}),...(fg('ufo_detect_aborting_interaction_during_ssr')?{'ufo:hasAbortingInteractionDuringSSR':getHasAbortingEventDuringSSR()}:{}),// root
|
|
15
15
|
...getBrowserMetadataToLegacyFormat(),...batteryInfo,...getSSRProperties(type),...getAssetsMetrics(interaction,pageLoadInteractionMetrics===null||pageLoadInteractionMetrics===void 0?void 0:pageLoadInteractionMetrics.SSRDoneTime),...getPPSMetrics(interaction),...paintMetrics,...getNavigationMetricsToLegacyFormat(type),...finalVCMetrics,...experimentalMetrics,...((_config$additionalPay=config.additionalPayloadData)===null||_config$additionalPay===void 0?void 0:_config$additionalPay.call(config,interaction)),...getTracingContextData(interaction),...getStylesheetMetrics(),...getErrorCounts(interaction),...getReactHydrationStats(),interactionMetrics:{namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId,pageVisibilityAtTTI,pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
|
|
16
16
|
rate,routeName,type,abortReason,featureFlags,previousInteractionName,isPreviousInteractionAborted,abortedByInteractionName,// performance
|
|
17
17
|
apdex:optimizeApdex(interaction.apdex,getReactUFOPayloadVersion(interaction.type)),end:Math.round(end),...(interaction.end3p?{end3p:Math.round(interaction.end3p)}:{}),start:Math.round(start),segments:getReactUFOPayloadVersion(interaction.type)==='2.0.0'?segmentTree:getOldSegmentsLabelStack(segments,interaction.type),marks:optimizeMarks(interaction.marks,getReactUFOPayloadVersion(interaction.type)),customData:optimizeCustomData(interaction),reactProfilerTimings:optimizeReactProfilerTimings(interaction.reactProfilerTimings,start,getReactUFOPayloadVersion(interaction.type)),minorInteractions:interaction.minorInteractions,...(responsiveness?{responsiveness}:{}),...labelStack,...pageLoadInteractionMetrics,...getDetailedInteractionMetrics(resourceTimings),...getPageLoadDetailedInteractionMetrics(),...getBm3TrackerTimings(interaction),'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI,...(unknownElementName?{unknownElementName}:{}),...(unknownElementHierarchy?{unknownElementHierarchy}:{})},'ufo:payloadTime':roundEpsilon(performance.now()-interactionPayloadStart)}}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if(fg('platform_ufo_enable_vc_raw_data')){const size=getPayloadSize(payload.attributes.properties);const vcRev=payload.attributes.properties['ufo:vc:rev'];const rawData=vcRev.find(item=>item.revision==='raw-handler');if(rawData){const rawDataSize=getPayloadSize(rawData);payload.attributes.properties['ufo:vc:raw:size']=rawDataSize;if(size>MAX_PAYLOAD_SIZE&&Array.isArray(vcRev)&&vcRev.length>0){payload.attributes.properties['ufo:vc:rev']=vcRev.filter(item=>item.revision!=='raw-handler');payload.attributes.properties['ufo:vc:raw:removed']=true;}}payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}else{payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}// in order of importance, first one being least important
|
|
18
18
|
// we can add more fields as necessary
|
|
19
|
-
const interactionMetricsFieldsToTrim=fg('ufo_remove_featureflags_from_trimmed_fields')?['requestInfo','resourceTimings']:['requestInfo','featureFlags','resourceTimings']
|
|
19
|
+
const interactionMetricsFieldsToTrim=fg('ufo_remove_featureflags_from_trimmed_fields')?['requestInfo','resourceTimings']:['requestInfo','featureFlags','resourceTimings'];// Top-level properties that can be trimmed if payload exceeds size limit
|
|
20
|
+
const topLevelFieldsToTrim=['ufo:pageVisibilityTimeline'];const properties=payload.attributes.properties;const interactionMetrics=properties.interactionMetrics;if(interactionMetrics){for(const field of interactionMetricsFieldsToTrim){if(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE){continue;}interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;let trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push(`interactionMetrics.${field}`);properties['event:trimmedFields']=trimmedFields;}}// Trim top-level properties if payload still exceeds the limit
|
|
21
|
+
for(const field of topLevelFieldsToTrim){if(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE){continue;}properties[field]=undefined;properties['event:isTrimmed']=true;let trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push(field);properties['event:trimmedFields']=trimmedFields;}// If the payload size continues to exceed the limit and interactionMetrics is already trimmed,
|
|
20
22
|
// trim VC debug data (early viewport checkpoints). PIR-30543 - AFO-5033
|
|
21
23
|
const isVCRevisionTrimEnabled=fg('ufo_vc_revision_trim_enabled');trimVcDebugData(properties,getPayloadSize(properties),MAX_PAYLOAD_SIZE,isVCRevisionTrimEnabled);return payload;}export async function createPayloads(interactionId,interaction){const ufoNameOverride=getUfoNameOverride(interaction);const modifiedInteraction={...interaction,ufoName:ufoNameOverride};const payloads=[];const isCriticalMetricsEnabled=fg('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
|
|
22
24
|
const vcMetrics=await getVCMetrics(interaction);// typeof Promise<CriticalMetricsPayload[]>
|
|
@@ -271,6 +271,57 @@ export function __injectThrottleMeasurementForTesting(measurement) {
|
|
|
271
271
|
throttleInsertIndex = (throttleInsertIndex + 1) % THROTTLE_BUFFER_SIZE;
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Returns the page visibility timeline entries within the specified time window.
|
|
276
|
+
* Each entry contains the time (relative to startTime) and whether the page was hidden.
|
|
277
|
+
*
|
|
278
|
+
* @param startTime - The start timestamp of the window (DOMHighResTimeStamp)
|
|
279
|
+
* @param endTime - The end timestamp of the window (DOMHighResTimeStamp)
|
|
280
|
+
* @returns Array of HiddenTimingItem entries within the time window, with times relative to startTime
|
|
281
|
+
*/
|
|
282
|
+
export function getPageVisibilityTimeline(startTime, endTime) {
|
|
283
|
+
// Input validation
|
|
284
|
+
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || startTime >= endTime) {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
if (timings.length === 0) {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
const result = [];
|
|
291
|
+
|
|
292
|
+
// Find the most recent entry at or before startTime to establish initial state
|
|
293
|
+
let initialEntry;
|
|
294
|
+
const currentSize = timings.length;
|
|
295
|
+
for (let i = 0; i < currentSize; i++) {
|
|
296
|
+
const idx = (insertIndex + i) % currentSize;
|
|
297
|
+
const entry = timings[idx];
|
|
298
|
+
if (entry && entry.time <= startTime) {
|
|
299
|
+
initialEntry = entry;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Add the initial visibility state at the start of the window
|
|
304
|
+
if (initialEntry) {
|
|
305
|
+
result.push({
|
|
306
|
+
time: 0,
|
|
307
|
+
hidden: initialEntry.hidden
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Add all entries within the time window
|
|
312
|
+
for (let i = 0; i < currentSize; i++) {
|
|
313
|
+
const idx = (insertIndex + i) % currentSize;
|
|
314
|
+
const entry = timings[idx];
|
|
315
|
+
if (entry && entry.time > startTime && entry.time <= endTime) {
|
|
316
|
+
result.push({
|
|
317
|
+
time: Math.round(entry.time - startTime),
|
|
318
|
+
hidden: entry.hidden
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
|
|
274
325
|
// Expose testing API on window for integration tests
|
|
275
326
|
if (typeof window !== 'undefined') {
|
|
276
327
|
window.__reactUfoHiddenTiming = {
|
|
@@ -1072,6 +1072,7 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
|
|
|
1072
1072
|
devToolsEnabled: config.vc.devToolsEnabled,
|
|
1073
1073
|
selectorConfig: config.vc.selectorConfig,
|
|
1074
1074
|
ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
|
|
1075
|
+
trackLayoutShiftOffenders: config.vc.trackLayoutShiftOffenders,
|
|
1075
1076
|
searchPageConfig
|
|
1076
1077
|
};
|
|
1077
1078
|
vcObserver = newVCObserver(vcOptions);
|
|
@@ -158,7 +158,8 @@ export function init(analyticsWebClientAsync, config) {
|
|
|
158
158
|
oldDomUpdates: config.vc.oldDomUpdates,
|
|
159
159
|
devToolsEnabled: config.vc.devToolsEnabled,
|
|
160
160
|
selectorConfig: config.vc.selectorConfig,
|
|
161
|
-
ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder
|
|
161
|
+
ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
|
|
162
|
+
trackLayoutShiftOffenders: config.vc.trackLayoutShiftOffenders
|
|
162
163
|
};
|
|
163
164
|
postInteractionLog.initializeVCObserver(vcOptions);
|
|
164
165
|
if (config !== null && config !== void 0 && (_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
|