@atlaskit/react-ufo 5.1.4 → 5.2.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 +20 -0
- package/dist/cjs/create-payload/index.js +3 -3
- package/dist/cjs/hidden-timing/index.js +135 -0
- package/dist/cjs/interaction-metrics-init/index.js +3 -0
- package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +1 -1
- package/dist/cjs/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +11 -19
- package/dist/es2019/create-payload/index.js +3 -3
- package/dist/es2019/hidden-timing/index.js +128 -0
- package/dist/es2019/interaction-metrics-init/index.js +4 -1
- package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +1 -1
- package/dist/es2019/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +12 -20
- package/dist/esm/create-payload/index.js +4 -4
- package/dist/esm/hidden-timing/index.js +130 -0
- package/dist/esm/interaction-metrics-init/index.js +4 -1
- package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +1 -1
- package/dist/esm/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +11 -19
- package/dist/types/common/react-ufo-payload-schema.d.ts +1 -0
- package/dist/types/hidden-timing/index.d.ts +42 -0
- package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +1 -0
- package/dist/types-ts4.5/hidden-timing/index.d.ts +42 -0
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @atlaskit/ufo-interaction-ignore
|
|
2
2
|
|
|
3
|
+
## 5.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`de657e97bdb75`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/de657e97bdb75) -
|
|
8
|
+
FG cleanup - platform_ufo_vc_ignore_display_none_mutations
|
|
9
|
+
|
|
10
|
+
## 5.2.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- [`b7f9d9f2e93dc`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b7f9d9f2e93dc) -
|
|
15
|
+
Detect browser throttling in UFO client
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [`03e2c7f2a7b38`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/03e2c7f2a7b38) -
|
|
20
|
+
Remove `featureFlags` field in the list of fields trimmed in the event of payload size exceeding
|
|
21
|
+
240KB
|
|
22
|
+
|
|
3
23
|
## 5.1.4
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -9,13 +9,13 @@ try{return acc+item.cssRules.length;}catch(_unused3){return acc;}},0);var styleE
|
|
|
9
9
|
getInitialPageLoadSSRMetrics=function getInitialPageLoadSSRMetrics(){var _config$ssr;if(!isPageLoad){return{};}var config=(0,_config.getConfig)();var SSRDoneTimeValue=(0,_getSsrDoneTimeValue.default)(config);var SSRDoneTime=SSRDoneTimeValue!==undefined?{SSRDoneTime:Math.round(SSRDoneTimeValue)}:{};var isBM3ConfigSSRDoneAsFmp=interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp;var isUFOConfigSSRDoneAsFmp=interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp||!!(config!==null&&config!==void 0&&(_config$ssr=config.ssr)!==null&&_config$ssr!==void 0&&_config$ssr.getSSRDoneTime);if(!experimental&&(isBM3ConfigSSRDoneAsFmp||isUFOConfigSSRDoneAsFmp)&&SSRDoneTimeValue!==undefined){try{performance.mark("FMP",{startTime:SSRDoneTimeValue,detail:{devtools:{dataType:'marker'}}});}catch(_unused6){}}return _objectSpread(_objectSpread({},SSRDoneTime),{},{isBM3ConfigSSRDoneAsFmp:isBM3ConfigSSRDoneAsFmp,isUFOConfigSSRDoneAsFmp:isUFOConfigSSRDoneAsFmp});};pageLoadInteractionMetrics=getInitialPageLoadSSRMetrics();// Detailed payload. Page visibility = visible
|
|
10
10
|
getDetailedInteractionMetrics=function getDetailedInteractionMetrics(resourceTimings){if(experimental||window.__UFO_COMPACT_PAYLOAD__||!isDetailedPayload){return{};}var spans=[].concat((0,_toConsumableArray2.default)(interaction.spans),(0,_toConsumableArray2.default)(_interactionMetrics.interactionSpans));_interactionMetrics.interactionSpans.length=0;var shouldInclude3pHolds=(0,_config.shouldUseRawDataThirdPartyBehavior)(ufoName,type);var basePayload={errors:interaction.errors.map(function(_ref2){var labelStack=_ref2.labelStack,others=(0,_objectWithoutProperties2.default)(_ref2,_excluded);return _objectSpread(_objectSpread({},others),{},{labelStack:labelStack&&(0,_utils.optimizeLabelStack)(labelStack,(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type))});}),holdActive:(0,_toConsumableArray2.default)(interaction.holdActive.values()),redirects:optimizeRedirects(interaction.redirects,start),holdInfo:(0,_optimizeHoldInfo.optimizeHoldInfo)(experimental?interaction.holdExpInfo:interaction.holdInfo,start,(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)),spans:(0,_optimizeSpans.optimizeSpans)(spans,start,(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)),requestInfo:(0,_optimizeRequestInfo.optimizeRequestInfo)(interaction.requestInfo,start,(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)),customTimings:(0,_optimizeCustomTimings.optimizeCustomTimings)(interaction.customTimings,start),bundleEvalTimings:objectToArray(getBundleEvalTimings(start)),resourceTimings:objectToArray(resourceTimings)};// Include third-party holds when feature flag is active
|
|
11
11
|
if(shouldInclude3pHolds){var _interaction$hold3pIn;return _objectSpread(_objectSpread({},basePayload),{},{hold3pActive:interaction.hold3pActive?(0,_toConsumableArray2.default)(interaction.hold3pActive.values()):[],hold3pInfo:(0,_optimizeHoldInfo.optimizeHoldInfo)((_interaction$hold3pIn=interaction.hold3pInfo)!==null&&_interaction$hold3pIn!==void 0?_interaction$hold3pIn:[],start,(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type))});}return basePayload;};// Page load & detailed payload
|
|
12
|
-
getPageLoadDetailedInteractionMetrics=function getPageLoadDetailedInteractionMetrics(){var _config$ssr2,_config$ssr2$getSSRTi;if(!isPageLoad||!isDetailedPayload){return{};}var initialPageLoadExtraTimings=objectToArray(initialPageLoadExtraTiming.getTimings());var config=(0,_config.getConfig)();var defaultSSRTimings=objectToArray(ssr.getSSRTimings());var ssrTimingsFromConfig=config===null||config===void 0||(_config$ssr2=config.ssr)===null||_config$ssr2===void 0||(_config$ssr2$getSSRTi=_config$ssr2.getSSRTimings)===null||_config$ssr2$getSSRTi===void 0?void 0:_config$ssr2$getSSRTi.call(_config$ssr2);return{initialPageLoadExtraTimings:initialPageLoadExtraTimings,SSRTimings:ssrTimingsFromConfig?[].concat((0,_toConsumableArray2.default)(ssrTimingsFromConfig),(0,_toConsumableArray2.default)(defaultSSRTimings)):defaultSSRTimings};};if(experimental){expTTAI=(0,_getTtai.default)(interaction);}else{regularTTAI=(0,_getTtai.default)(interaction);}newUFOName=(0,_utils.sanitizeUfoName)(ufoName);resourceTimings=getResourceTimings(start,end);_context.t0=Promise;_context.t1=vcMetrics;if(_context.t1){_context.next=29;break;}_context.next=28;return(0,_getVcMetrics.default)(interaction);case 28:_context.t1=_context.sent;case 29:_context.t2=_context.t1;_context.t3=experimental?(0,_createExperimentalInteractionMetricsPayload.getExperimentalVCMetrics)(interaction):Promise.resolve(undefined);_context.t4=(0,_getPaintMetrics.getPaintMetricsToLegacyFormat)(type,end);_context.t5=(0,_getBatteryInfo.getBatteryInfoToLegacyFormat)();_context.t6=[_context.t2,_context.t3,_context.t4,_context.t5];_context.next=36;return _context.t0.all.call(_context.t0,_context.t6);case 36:_yield$Promise$all=_context.sent;_yield$Promise$all2=(0,_slicedToArray2.default)(_yield$Promise$all,4);finalVCMetrics=_yield$Promise$all2[0];experimentalMetrics=_yield$Promise$all2[1];paintMetrics=_yield$Promise$all2[2];batteryInfo=_yield$Promise$all2[3];if(!experimental){(0,_addPerformanceMeasures.addPerformanceMeasures)(interaction.start,(0,_toConsumableArray2.default)((finalVCMetrics===null||finalVCMetrics===void 0?void 0:finalVCMetrics['ufo:vc:rev'])||[]));}getReactHydrationStats=function getReactHydrationStats(){if(!hydration){return{};}return{hydration:hydration};};payload={actionSubject:'experience',action:'measured',eventType:'operational',source:'measured',tags:['observability'],attributes:{properties:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({// basic
|
|
12
|
+
getPageLoadDetailedInteractionMetrics=function getPageLoadDetailedInteractionMetrics(){var _config$ssr2,_config$ssr2$getSSRTi;if(!isPageLoad||!isDetailedPayload){return{};}var initialPageLoadExtraTimings=objectToArray(initialPageLoadExtraTiming.getTimings());var config=(0,_config.getConfig)();var defaultSSRTimings=objectToArray(ssr.getSSRTimings());var ssrTimingsFromConfig=config===null||config===void 0||(_config$ssr2=config.ssr)===null||_config$ssr2===void 0||(_config$ssr2$getSSRTi=_config$ssr2.getSSRTimings)===null||_config$ssr2$getSSRTi===void 0?void 0:_config$ssr2$getSSRTi.call(_config$ssr2);return{initialPageLoadExtraTimings:initialPageLoadExtraTimings,SSRTimings:ssrTimingsFromConfig?[].concat((0,_toConsumableArray2.default)(ssrTimingsFromConfig),(0,_toConsumableArray2.default)(defaultSSRTimings)):defaultSSRTimings};};if(experimental){expTTAI=(0,_getTtai.default)(interaction);}else{regularTTAI=(0,_getTtai.default)(interaction);}newUFOName=(0,_utils.sanitizeUfoName)(ufoName);resourceTimings=getResourceTimings(start,end);_context.t0=Promise;_context.t1=vcMetrics;if(_context.t1){_context.next=29;break;}_context.next=28;return(0,_getVcMetrics.default)(interaction);case 28:_context.t1=_context.sent;case 29:_context.t2=_context.t1;_context.t3=experimental?(0,_createExperimentalInteractionMetricsPayload.getExperimentalVCMetrics)(interaction):Promise.resolve(undefined);_context.t4=(0,_getPaintMetrics.getPaintMetricsToLegacyFormat)(type,end);_context.t5=(0,_getBatteryInfo.getBatteryInfoToLegacyFormat)();_context.t6=[_context.t2,_context.t3,_context.t4,_context.t5];_context.next=36;return _context.t0.all.call(_context.t0,_context.t6);case 36:_yield$Promise$all=_context.sent;_yield$Promise$all2=(0,_slicedToArray2.default)(_yield$Promise$all,4);finalVCMetrics=_yield$Promise$all2[0];experimentalMetrics=_yield$Promise$all2[1];paintMetrics=_yield$Promise$all2[2];batteryInfo=_yield$Promise$all2[3];if(!experimental){(0,_addPerformanceMeasures.addPerformanceMeasures)(interaction.start,(0,_toConsumableArray2.default)((finalVCMetrics===null||finalVCMetrics===void 0?void 0:finalVCMetrics['ufo:vc:rev'])||[]));}getReactHydrationStats=function getReactHydrationStats(){if(!hydration){return{};}return{hydration:hydration};};payload={actionSubject:'experience',action:'measured',eventType:'operational',source:'measured',tags:['observability'],attributes:{properties:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({// 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:(0,_getReactUfoPayloadVersion.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':(0,_machineUtilisation.createPressureStateReport)(interaction.start,interaction.end),'event:memory:usage':(0,_machineUtilisation.createMemoryStateReport)(interaction.start,interaction.end)},criticalPayloadCount!==undefined?{'ufo:multipayload':true,'ufo:criticalPayloadCount':criticalPayloadCount}:{}),(0,_platformFeatureFlags.fg)('platform_ufo_browser_backgrounded_abort_timestamp')?{'ufo:pageVisibilityHiddenTimestamp':(0,_hiddenTiming.getEarliestHiddenTiming)(interaction.start,interaction.end)}:{}),{},{'ufo:wasPageHiddenBeforeInit':(0,_hiddenTiming.getHasHiddenTimingBeforeSetup)(),'ufo:isOpenedInBackground':(0,_hiddenTiming.isOpenedInBackground)(interaction.type)},(0,_getBrowserMetadata.getBrowserMetadataToLegacyFormat)()),batteryInfo),getSSRProperties(type)),getAssetsMetrics(interaction,pageLoadInteractionMetrics===null||pageLoadInteractionMetrics===void 0?void 0:pageLoadInteractionMetrics.SSRDoneTime)),getPPSMetrics(interaction)),paintMetrics),(0,_getNavigationMetrics.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:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId:interactionId,pageVisibilityAtTTI:pageVisibilityAtTTI,pageVisibilityAtTTAI:pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
|
|
14
|
+
'event:cpu:usage':(0,_machineUtilisation.createPressureStateReport)(interaction.start,interaction.end),'event:memory:usage':(0,_machineUtilisation.createMemoryStateReport)(interaction.start,interaction.end)},criticalPayloadCount!==undefined?{'ufo:multipayload':true,'ufo:criticalPayloadCount':criticalPayloadCount}:{}),(0,_platformFeatureFlags.fg)('platform_ufo_browser_backgrounded_abort_timestamp')?{'ufo:pageVisibilityHiddenTimestamp':(0,_hiddenTiming.getEarliestHiddenTiming)(interaction.start,interaction.end)}:{}),{},{'ufo:wasPageHiddenBeforeInit':(0,_hiddenTiming.getHasHiddenTimingBeforeSetup)(),'ufo:isOpenedInBackground':(0,_hiddenTiming.isOpenedInBackground)(interaction.type)},(0,_platformFeatureFlags.fg)('platform_ufo_is_tab_throttled')?{'ufo:isTabThrottled':(0,_hiddenTiming.isTabThrottled)(start,end)}:{}),(0,_getBrowserMetadata.getBrowserMetadataToLegacyFormat)()),batteryInfo),getSSRProperties(type)),getAssetsMetrics(interaction,pageLoadInteractionMetrics===null||pageLoadInteractionMetrics===void 0?void 0:pageLoadInteractionMetrics.SSRDoneTime)),getPPSMetrics(interaction)),paintMetrics),(0,_getNavigationMetrics.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:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId:interactionId,pageVisibilityAtTTI:pageVisibilityAtTTI,pageVisibilityAtTTAI:pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
|
|
15
15
|
rate:rate,routeName:routeName,type:type,abortReason:abortReason,featureFlags:featureFlags,previousInteractionName:previousInteractionName,isPreviousInteractionAborted:isPreviousInteractionAborted,abortedByInteractionName:abortedByInteractionName,// performance
|
|
16
16
|
apdex:(0,_optimizeApdex.optimizeApdex)(interaction.apdex,(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)),end:Math.round(end)},interaction.end3p?{end3p:Math.round(interaction.end3p)}:{}),{},{start:Math.round(start),segments:(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)==='2.0.0'?segmentTree:(0,_utils.getOldSegmentsLabelStack)(segments,interaction.type),marks:(0,_optimizeMarks.optimizeMarks)(interaction.marks,(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)),customData:optimizeCustomData(interaction),reactProfilerTimings:(0,_optimizeReactProfilerTimings.optimizeReactProfilerTimings)(interaction.reactProfilerTimings,start,(0,_getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)),minorInteractions:interaction.minorInteractions},responsiveness?{responsiveness:responsiveness}:{}),labelStack),pageLoadInteractionMetrics),getDetailedInteractionMetrics(resourceTimings)),getPageLoadDetailedInteractionMetrics()),getBm3TrackerTimings(interaction)),{},{'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI},unknownElementName?{unknownElementName:unknownElementName}:{}),unknownElementHierarchy?{unknownElementHierarchy:unknownElementHierarchy}:{}),'ufo:payloadTime':(0,_roundNumber.roundEpsilon)(performance.now()-interactionPayloadStart)})}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if((0,_platformFeatureFlags.fg)('platform_ufo_enable_vc_raw_data')){size=(0,_getPayloadSize.default)(payload.attributes.properties);vcRev=payload.attributes.properties['ufo:vc:rev'];rawData=vcRev.find(function(item){return item.revision==='raw-handler';});if(rawData){rawDataSize=(0,_getPayloadSize.default)(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(function(item){return item.revision!=='raw-handler';});payload.attributes.properties['ufo:vc:raw:removed']=true;}}payload.attributes.properties['event:sizeInKb']=(0,_getPayloadSize.default)(payload.attributes.properties);}else{payload.attributes.properties['event:sizeInKb']=(0,_getPayloadSize.default)(payload.attributes.properties);}// in order of importance, first one being least important
|
|
17
17
|
// we can add more fields as necessary
|
|
18
|
-
interactionMetricsFieldsToTrim=['requestInfo','featureFlags','resourceTimings'];properties=payload.attributes.properties;interactionMetrics=properties.interactionMetrics;if(!interactionMetrics){_context.next=74;break;}_iterator=_createForOfIteratorHelper(interactionMetricsFieldsToTrim);_context.prev=52;_iterator.s();case 54:if((_step=_iterator.n()).done){_context.next=66;break;}field=_step.value;if(!((0,_getPayloadSize.default)(properties)<=MAX_PAYLOAD_SIZE)){_context.next=58;break;}return _context.abrupt("continue",64);case 58:interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push("interactionMetrics.".concat(field));properties['event:trimmedFields']=trimmedFields;case 64:_context.next=54;break;case 66:_context.next=71;break;case 68:_context.prev=68;_context.t7=_context["catch"](52);_iterator.e(_context.t7);case 71:_context.prev=71;_iterator.f();return _context.finish(71);case 74:return _context.abrupt("return",payload);case 75:case"end":return _context.stop();}},_callee,null,[[52,68,71,74]]);}));return _createInteractionMetricsPayload.apply(this,arguments);}function createPayloads(_x6,_x7){return _createPayloads.apply(this,arguments);}function _createPayloads(){_createPayloads=(0,_asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2(interactionId,interaction){var ufoNameOverride,modifiedInteraction,payloads,isCriticalMetricsEnabled,vcMetrics,criticalMetricsPayloads,criticalPayloadCount,interactionMetricsPayload;return _regenerator.default.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:ufoNameOverride=getUfoNameOverride(interaction);modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{ufoName:ufoNameOverride});payloads=[];isCriticalMetricsEnabled=(0,_platformFeatureFlags.fg)('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
|
|
18
|
+
interactionMetricsFieldsToTrim=(0,_platformFeatureFlags.fg)('ufo_remove_featureflags_from_trimmed_fields')?['requestInfo','resourceTimings']:['requestInfo','featureFlags','resourceTimings'];properties=payload.attributes.properties;interactionMetrics=properties.interactionMetrics;if(!interactionMetrics){_context.next=74;break;}_iterator=_createForOfIteratorHelper(interactionMetricsFieldsToTrim);_context.prev=52;_iterator.s();case 54:if((_step=_iterator.n()).done){_context.next=66;break;}field=_step.value;if(!((0,_getPayloadSize.default)(properties)<=MAX_PAYLOAD_SIZE)){_context.next=58;break;}return _context.abrupt("continue",64);case 58:interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push("interactionMetrics.".concat(field));properties['event:trimmedFields']=trimmedFields;case 64:_context.next=54;break;case 66:_context.next=71;break;case 68:_context.prev=68;_context.t7=_context["catch"](52);_iterator.e(_context.t7);case 71:_context.prev=71;_iterator.f();return _context.finish(71);case 74:return _context.abrupt("return",payload);case 75:case"end":return _context.stop();}},_callee,null,[[52,68,71,74]]);}));return _createInteractionMetricsPayload.apply(this,arguments);}function createPayloads(_x6,_x7){return _createPayloads.apply(this,arguments);}function _createPayloads(){_createPayloads=(0,_asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee2(interactionId,interaction){var ufoNameOverride,modifiedInteraction,payloads,isCriticalMetricsEnabled,vcMetrics,criticalMetricsPayloads,criticalPayloadCount,interactionMetricsPayload;return _regenerator.default.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:ufoNameOverride=getUfoNameOverride(interaction);modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{ufoName:ufoNameOverride});payloads=[];isCriticalMetricsEnabled=(0,_platformFeatureFlags.fg)('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
|
|
19
19
|
_context2.next=6;return(0,_getVcMetrics.default)(interaction);case 6:vcMetrics=_context2.sent;if(!isCriticalMetricsEnabled){_context2.next=13;break;}_context2.next=10;return(0,_criticalMetricsPayload.createCriticalMetricsPayloads)(interactionId,interaction,vcMetrics);case 10:_context2.t0=_context2.sent;_context2.next=14;break;case 13:_context2.t0=[];case 14:criticalMetricsPayloads=_context2.t0;payloads.push.apply(payloads,(0,_toConsumableArray2.default)(criticalMetricsPayloads));criticalPayloadCount=isCriticalMetricsEnabled?criticalMetricsPayloads.length:undefined;_context2.next=19;return createInteractionMetricsPayload(modifiedInteraction,interactionId,undefined,criticalPayloadCount,vcMetrics);case 19:interactionMetricsPayload=_context2.sent;payloads.push(interactionMetricsPayload);return _context2.abrupt("return",payloads.filter(Boolean));case 22:case"end":return _context2.stop();}},_callee2);}));return _createPayloads.apply(this,arguments);}function createExperimentalMetricsPayload(_x8,_x9){return _createExperimentalMetricsPayload.apply(this,arguments);}function _createExperimentalMetricsPayload(){_createExperimentalMetricsPayload=(0,_asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee3(interactionId,interaction){var config,ufoName,rate,pageVisibilityState,result;return _regenerator.default.wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:config=(0,_config.getConfig)();if(config){_context3.next=3;break;}throw Error('UFO Configuration not provided');case 3:ufoName=(0,_utils.sanitizeUfoName)(interaction.ufoName);rate=(0,_config.getExperimentalInteractionRate)(ufoName,interaction.type);if((0,_coinflip.default)(rate)){_context3.next=7;break;}return _context3.abrupt("return",null);case 7:pageVisibilityState=(0,_hiddenTiming.getPageVisibilityState)(interaction.start,interaction.end);if(!(pageVisibilityState!=='visible')){_context3.next=10;break;}return _context3.abrupt("return",null);case 10:_context3.next=12;return createInteractionMetricsPayload(interaction,interactionId,true);case 12:result=_context3.sent;return _context3.abrupt("return",result);case 14:case"end":return _context3.stop();}},_callee3);}));return _createExperimentalMetricsPayload.apply(this,arguments);}function createExtraSearchPageInteractionPayload(_x0,_x1){return _createExtraSearchPageInteractionPayload.apply(this,arguments);}function _createExtraSearchPageInteractionPayload(){_createExtraSearchPageInteractionPayload=(0,_asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee4(interactionId,interaction){var SAIN_HOLD_NAMES,NAME_OVERRIDE,SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL,newInteractionId,newEnd,holdInfo,reactProfilerTimings,lastHold,isLastHoldSAIN,lastFilteredTime,filteredReactProfilerTimings,lastTiming,modifiedInteraction,payloads,vcMetrics,interactionMetricsPayload;return _regenerator.default.wrap(function _callee4$(_context4){while(1)switch(_context4.prev=_context4.next){case 0:SAIN_HOLD_NAMES=['search-ai-dialog-visible-text-loading','search-ai-dialog-all-text-loading'];NAME_OVERRIDE='search-page-ignoring-smart-answers';SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL='search-page-smart-answers';newInteractionId="".concat(interactionId,"-ignoring-smart-answers");// Calculate a new end time which excludes SAIN holds
|
|
20
20
|
holdInfo=interaction.holdInfo,reactProfilerTimings=interaction.reactProfilerTimings;lastHold=holdInfo.at(-1);isLastHoldSAIN=Boolean(lastHold&&SAIN_HOLD_NAMES.includes(lastHold.name));// A new end time is only calculated if the last hold is a SAIN hold
|
|
21
21
|
if(isLastHoldSAIN){lastFilteredTime=null;filteredReactProfilerTimings=reactProfilerTimings.filter(function(timing){if(timing.commitTime===lastFilteredTime){return false;}var isTimingSmartAnswersInSearch=timing.labelStack.some(function(label){return label.name===SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL;});if(isTimingSmartAnswersInSearch){lastFilteredTime=timing.commitTime;return false;}return true;});lastTiming=filteredReactProfilerTimings.at(-1);if(lastTiming){newEnd=lastTiming.commitTime;}}modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{end:newEnd!==null&&newEnd!==void 0?newEnd:interaction.end,holdInfo:[],knownSegments:[],reactProfilerTimings:[],ufoName:NAME_OVERRIDE});payloads=[];_context4.next=12;return(0,_getVcMetrics.default)(interaction,false,true);case 12:vcMetrics=_context4.sent;_context4.next=15;return createInteractionMetricsPayload(modifiedInteraction,newInteractionId,undefined,undefined,vcMetrics);case 15:interactionMetricsPayload=_context4.sent;payloads.push(interactionMetricsPayload);return _context4.abrupt("return",payloads.filter(Boolean));case 18:case"end":return _context4.stop();}},_callee4);}));return _createExtraSearchPageInteractionPayload.apply(this,arguments);}
|
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.__injectThrottleMeasurementForTesting = __injectThrottleMeasurementForTesting;
|
|
6
7
|
exports.getEarliestHiddenTiming = getEarliestHiddenTiming;
|
|
7
8
|
exports.getHasHiddenTimingBeforeSetup = getHasHiddenTimingBeforeSetup;
|
|
8
9
|
exports.getPageVisibilityState = getPageVisibilityState;
|
|
10
|
+
exports.getThrottleMeasurements = getThrottleMeasurements;
|
|
9
11
|
exports.isOpenedInBackground = isOpenedInBackground;
|
|
12
|
+
exports.isTabThrottled = isTabThrottled;
|
|
10
13
|
exports.setupHiddenTimingCapture = setupHiddenTimingCapture;
|
|
14
|
+
exports.setupThrottleDetection = setupThrottleDetection;
|
|
15
|
+
exports.stopThrottleDetection = stopThrottleDetection;
|
|
11
16
|
var _bindEventListener = require("bind-event-listener");
|
|
12
17
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
13
18
|
var timings = [];
|
|
@@ -161,4 +166,134 @@ function getPageVisibilityState(start, end) {
|
|
|
161
166
|
hiddenState = timings[startIdx].hidden ? 'hidden' : 'visible';
|
|
162
167
|
}
|
|
163
168
|
return hiddenState;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Throttle detection configuration
|
|
172
|
+
// Expected interval for timer checks (in milliseconds)
|
|
173
|
+
var THROTTLE_CHECK_INTERVAL_MS = 1000;
|
|
174
|
+
// Threshold for considering a timer as throttled (50% drift tolerance)
|
|
175
|
+
var THROTTLE_DRIFT_THRESHOLD = 1.5;
|
|
176
|
+
// Maximum number of throttle measurements to store (circular buffer)
|
|
177
|
+
var THROTTLE_BUFFER_SIZE = 120;
|
|
178
|
+
// Circular buffer to store throttle measurements
|
|
179
|
+
var throttleMeasurements = [];
|
|
180
|
+
var throttleInsertIndex = 0;
|
|
181
|
+
var throttleIntervalId = null;
|
|
182
|
+
var lastThrottleCheckTime = null;
|
|
183
|
+
var throttleSetupDone = false;
|
|
184
|
+
function recordThrottleMeasurement(expectedElapsed, actualElapsed) {
|
|
185
|
+
var isThrottled = actualElapsed > expectedElapsed * THROTTLE_DRIFT_THRESHOLD;
|
|
186
|
+
throttleMeasurements[throttleInsertIndex] = {
|
|
187
|
+
time: performance.now(),
|
|
188
|
+
expectedElapsed: expectedElapsed,
|
|
189
|
+
actualElapsed: actualElapsed,
|
|
190
|
+
isThrottled: isThrottled
|
|
191
|
+
};
|
|
192
|
+
throttleInsertIndex = (throttleInsertIndex + 1) % THROTTLE_BUFFER_SIZE;
|
|
193
|
+
}
|
|
194
|
+
function throttleCheckCallback() {
|
|
195
|
+
var currentTime = performance.now();
|
|
196
|
+
if (lastThrottleCheckTime !== null) {
|
|
197
|
+
var actualElapsed = currentTime - lastThrottleCheckTime;
|
|
198
|
+
recordThrottleMeasurement(THROTTLE_CHECK_INTERVAL_MS, actualElapsed);
|
|
199
|
+
}
|
|
200
|
+
lastThrottleCheckTime = currentTime;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Sets up the throttle detection mechanism.
|
|
205
|
+
* This should be called early in the page lifecycle.
|
|
206
|
+
* Uses a periodic timer to detect browser throttling by measuring timer drift.
|
|
207
|
+
*/
|
|
208
|
+
function setupThrottleDetection() {
|
|
209
|
+
if (throttleSetupDone) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
throttleSetupDone = true;
|
|
213
|
+
|
|
214
|
+
// Record the initial timestamp
|
|
215
|
+
lastThrottleCheckTime = performance.now();
|
|
216
|
+
|
|
217
|
+
// Start the periodic timer for throttle detection
|
|
218
|
+
throttleIntervalId = setInterval(throttleCheckCallback, THROTTLE_CHECK_INTERVAL_MS);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Stops the throttle detection mechanism.
|
|
223
|
+
* Useful for cleanup in tests or when the feature is no longer needed.
|
|
224
|
+
*/
|
|
225
|
+
function stopThrottleDetection() {
|
|
226
|
+
if (throttleIntervalId !== null) {
|
|
227
|
+
clearInterval(throttleIntervalId);
|
|
228
|
+
throttleIntervalId = null;
|
|
229
|
+
}
|
|
230
|
+
lastThrottleCheckTime = null;
|
|
231
|
+
throttleSetupDone = false;
|
|
232
|
+
throttleMeasurements.length = 0;
|
|
233
|
+
throttleInsertIndex = 0;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Checks if the tab was throttled at any point during the specified time window.
|
|
238
|
+
* Returns true if any timer measurement showed significant drift (throttling).
|
|
239
|
+
*
|
|
240
|
+
* @param startTime - The start timestamp of the window to check (DOMHighResTimeStamp)
|
|
241
|
+
* @param endTime - The end timestamp of the window to check (DOMHighResTimeStamp)
|
|
242
|
+
* @returns boolean - true if throttling was detected during the time window, false otherwise
|
|
243
|
+
*/
|
|
244
|
+
function isTabThrottled(startTime, endTime) {
|
|
245
|
+
// Input validation
|
|
246
|
+
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || startTime >= endTime) {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// No measurements available
|
|
251
|
+
if (throttleMeasurements.length === 0) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Check if any measurement within the time window indicates throttling
|
|
256
|
+
for (var i = 0; i < throttleMeasurements.length; i++) {
|
|
257
|
+
var measurement = throttleMeasurements[i];
|
|
258
|
+
if (measurement && measurement.time >= startTime && measurement.time <= endTime && measurement.isThrottled) {
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Gets detailed throttle information for debugging purposes.
|
|
267
|
+
* Returns all throttle measurements within the specified time window.
|
|
268
|
+
*
|
|
269
|
+
* @param startTime - The start timestamp of the window to check
|
|
270
|
+
* @param endTime - The end timestamp of the window to check
|
|
271
|
+
* @returns Array of throttle measurements within the time window
|
|
272
|
+
*/
|
|
273
|
+
function getThrottleMeasurements(startTime, endTime) {
|
|
274
|
+
// Input validation
|
|
275
|
+
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || startTime >= endTime) {
|
|
276
|
+
return [];
|
|
277
|
+
}
|
|
278
|
+
return throttleMeasurements.filter(function (measurement) {
|
|
279
|
+
return measurement && measurement.time >= startTime && measurement.time <= endTime;
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Injects a fake throttle measurement for testing purposes.
|
|
285
|
+
* This allows integration tests to simulate throttling scenarios.
|
|
286
|
+
*
|
|
287
|
+
* @param measurement - The throttle measurement to inject
|
|
288
|
+
*/
|
|
289
|
+
function __injectThrottleMeasurementForTesting(measurement) {
|
|
290
|
+
throttleMeasurements[throttleInsertIndex] = measurement;
|
|
291
|
+
throttleInsertIndex = (throttleInsertIndex + 1) % THROTTLE_BUFFER_SIZE;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Expose testing API on window for integration tests
|
|
295
|
+
if (typeof window !== 'undefined') {
|
|
296
|
+
window.__reactUfoHiddenTiming = {
|
|
297
|
+
__injectThrottleMeasurementForTesting: __injectThrottleMeasurementForTesting
|
|
298
|
+
};
|
|
164
299
|
}
|
|
@@ -187,6 +187,9 @@ function init(analyticsWebClientAsync, config) {
|
|
|
187
187
|
}
|
|
188
188
|
(0, _hiddenTiming.setupHiddenTimingCapture)();
|
|
189
189
|
(0, _additionalPayload.startLighthouseObserver)();
|
|
190
|
+
if ((0, _platformFeatureFlags.fg)('platform_ufo_is_tab_throttled')) {
|
|
191
|
+
(0, _hiddenTiming.setupThrottleDetection)();
|
|
192
|
+
}
|
|
190
193
|
initialized = true;
|
|
191
194
|
if (typeof PerformanceObserver !== 'undefined') {
|
|
192
195
|
var observer = (0, _interactionsPerformanceObserver.getPerformanceObserver)();
|
|
@@ -52,7 +52,7 @@ var VCCalculator_FY25_03 = exports.default = /*#__PURE__*/function (_AbstractVCC
|
|
|
52
52
|
if (!getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch).includes(entry.data.type)) {
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
|
-
if (entry.data.type === 'mutation:attribute:framework-routing'
|
|
55
|
+
if (entry.data.type === 'mutation:attribute:framework-routing') {
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
58
|
if (excludeSmartAnswersInSearch && (0, _isEntrySmartAnswersInSearch.isEntrySmartAnswersInSearch)(entry) && !(0, _platformFeatureFlags.fg)('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.createIntersectionObserver = createIntersectionObserver;
|
|
7
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
8
7
|
var _isZeroDimensionRectangle = require("../utils/is-zero-dimension-rectangle");
|
|
9
8
|
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; } } }; }
|
|
10
9
|
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; } }
|
|
@@ -38,28 +37,21 @@ function createIntersectionObserver(_ref) {
|
|
|
38
37
|
|
|
39
38
|
// override as display-contents mutation
|
|
40
39
|
if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute') {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (isRoutingMutation) {
|
|
48
|
-
return {
|
|
49
|
-
type: 'mutation:attribute:framework-routing',
|
|
50
|
-
mutationData: tagOrCallbackResult.mutationData
|
|
51
|
-
};
|
|
52
|
-
}
|
|
40
|
+
var _tagOrCallbackResult$ = tagOrCallbackResult.mutationData,
|
|
41
|
+
attributeName = _tagOrCallbackResult$.attributeName,
|
|
42
|
+
oldValue = _tagOrCallbackResult$.oldValue,
|
|
43
|
+
newValue = _tagOrCallbackResult$.newValue;
|
|
44
|
+
var isRoutingMutation = attributeName === 'style' && (!oldValue && newValue === 'display: none !important;' || oldValue === 'display: none !important;' && !newValue);
|
|
45
|
+
if (isRoutingMutation) {
|
|
53
46
|
return {
|
|
54
|
-
type: 'mutation:
|
|
55
|
-
mutationData: tagOrCallbackResult.mutationData
|
|
56
|
-
};
|
|
57
|
-
} else {
|
|
58
|
-
return {
|
|
59
|
-
type: 'mutation:display-contents-children-attribute',
|
|
47
|
+
type: 'mutation:attribute:framework-routing',
|
|
60
48
|
mutationData: tagOrCallbackResult.mutationData
|
|
61
49
|
};
|
|
62
50
|
}
|
|
51
|
+
return {
|
|
52
|
+
type: 'mutation:display-contents-children-attribute',
|
|
53
|
+
mutationData: tagOrCallbackResult.mutationData
|
|
54
|
+
};
|
|
63
55
|
}
|
|
64
56
|
return tagOrCallbackResult;
|
|
65
57
|
};
|
|
@@ -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}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{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';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,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{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';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,12 @@ 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}:{}),...(fg('platform_ufo_browser_backgrounded_abort_timestamp')?{'ufo:pageVisibilityHiddenTimestamp':getEarliestHiddenTiming(interaction.start,interaction.end)}:{}),'ufo:wasPageHiddenBeforeInit':getHasHiddenTimingBeforeSetup(),'ufo:isOpenedInBackground':isOpenedInBackground(interaction.type),// 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}:{}),...(fg('platform_ufo_browser_backgrounded_abort_timestamp')?{'ufo:pageVisibilityHiddenTimestamp':getEarliestHiddenTiming(interaction.start,interaction.end)}:{}),'ufo:wasPageHiddenBeforeInit':getHasHiddenTimingBeforeSetup(),'ufo:isOpenedInBackground':isOpenedInBackground(interaction.type),...(fg('platform_ufo_is_tab_throttled')?{'ufo:isTabThrottled':isTabThrottled(start,end)}:{}),// 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=['requestInfo','featureFlags','resourceTimings'];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;}}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
|
|
19
|
+
const interactionMetricsFieldsToTrim=fg('ufo_remove_featureflags_from_trimmed_fields')?['requestInfo','resourceTimings']:['requestInfo','featureFlags','resourceTimings'];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;}}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
|
|
20
20
|
const vcMetrics=await getVCMetrics(interaction);// typeof Promise<CriticalMetricsPayload[]>
|
|
21
21
|
const criticalMetricsPayloads=isCriticalMetricsEnabled?await createCriticalMetricsPayloads(interactionId,interaction,vcMetrics):[];payloads.push(...criticalMetricsPayloads);const criticalPayloadCount=isCriticalMetricsEnabled?criticalMetricsPayloads.length:undefined;const interactionMetricsPayload=await createInteractionMetricsPayload(modifiedInteraction,interactionId,undefined,criticalPayloadCount,vcMetrics);payloads.push(interactionMetricsPayload);return payloads.filter(Boolean);}export async function createExperimentalMetricsPayload(interactionId,interaction){const config=getConfig();if(!config){throw Error('UFO Configuration not provided');}const ufoName=sanitizeUfoName(interaction.ufoName);const rate=getExperimentalInteractionRate(ufoName,interaction.type);if(!coinflip(rate)){return null;}const pageVisibilityState=getPageVisibilityState(interaction.start,interaction.end);if(pageVisibilityState!=='visible'){return null;}const result=await createInteractionMetricsPayload(interaction,interactionId,true);return result;}export async function createExtraSearchPageInteractionPayload(interactionId,interaction){var _newEnd;const SAIN_HOLD_NAMES=['search-ai-dialog-visible-text-loading','search-ai-dialog-all-text-loading'];const NAME_OVERRIDE='search-page-ignoring-smart-answers';const SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL='search-page-smart-answers';const newInteractionId=`${interactionId}-ignoring-smart-answers`;// Calculate a new end time which excludes SAIN holds
|
|
22
22
|
let newEnd;const{holdInfo,reactProfilerTimings}=interaction;const lastHold=holdInfo.at(-1);const isLastHoldSAIN=Boolean(lastHold&&SAIN_HOLD_NAMES.includes(lastHold.name));// A new end time is only calculated if the last hold is a SAIN hold
|
|
@@ -148,4 +148,132 @@ export function getPageVisibilityState(start, end) {
|
|
|
148
148
|
hiddenState = timings[startIdx].hidden ? 'hidden' : 'visible';
|
|
149
149
|
}
|
|
150
150
|
return hiddenState;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Throttle detection configuration
|
|
154
|
+
// Expected interval for timer checks (in milliseconds)
|
|
155
|
+
const THROTTLE_CHECK_INTERVAL_MS = 1000;
|
|
156
|
+
// Threshold for considering a timer as throttled (50% drift tolerance)
|
|
157
|
+
const THROTTLE_DRIFT_THRESHOLD = 1.5;
|
|
158
|
+
// Maximum number of throttle measurements to store (circular buffer)
|
|
159
|
+
const THROTTLE_BUFFER_SIZE = 120;
|
|
160
|
+
// Circular buffer to store throttle measurements
|
|
161
|
+
const throttleMeasurements = [];
|
|
162
|
+
let throttleInsertIndex = 0;
|
|
163
|
+
let throttleIntervalId = null;
|
|
164
|
+
let lastThrottleCheckTime = null;
|
|
165
|
+
let throttleSetupDone = false;
|
|
166
|
+
function recordThrottleMeasurement(expectedElapsed, actualElapsed) {
|
|
167
|
+
const isThrottled = actualElapsed > expectedElapsed * THROTTLE_DRIFT_THRESHOLD;
|
|
168
|
+
throttleMeasurements[throttleInsertIndex] = {
|
|
169
|
+
time: performance.now(),
|
|
170
|
+
expectedElapsed,
|
|
171
|
+
actualElapsed,
|
|
172
|
+
isThrottled
|
|
173
|
+
};
|
|
174
|
+
throttleInsertIndex = (throttleInsertIndex + 1) % THROTTLE_BUFFER_SIZE;
|
|
175
|
+
}
|
|
176
|
+
function throttleCheckCallback() {
|
|
177
|
+
const currentTime = performance.now();
|
|
178
|
+
if (lastThrottleCheckTime !== null) {
|
|
179
|
+
const actualElapsed = currentTime - lastThrottleCheckTime;
|
|
180
|
+
recordThrottleMeasurement(THROTTLE_CHECK_INTERVAL_MS, actualElapsed);
|
|
181
|
+
}
|
|
182
|
+
lastThrottleCheckTime = currentTime;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Sets up the throttle detection mechanism.
|
|
187
|
+
* This should be called early in the page lifecycle.
|
|
188
|
+
* Uses a periodic timer to detect browser throttling by measuring timer drift.
|
|
189
|
+
*/
|
|
190
|
+
export function setupThrottleDetection() {
|
|
191
|
+
if (throttleSetupDone) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
throttleSetupDone = true;
|
|
195
|
+
|
|
196
|
+
// Record the initial timestamp
|
|
197
|
+
lastThrottleCheckTime = performance.now();
|
|
198
|
+
|
|
199
|
+
// Start the periodic timer for throttle detection
|
|
200
|
+
throttleIntervalId = setInterval(throttleCheckCallback, THROTTLE_CHECK_INTERVAL_MS);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Stops the throttle detection mechanism.
|
|
205
|
+
* Useful for cleanup in tests or when the feature is no longer needed.
|
|
206
|
+
*/
|
|
207
|
+
export function stopThrottleDetection() {
|
|
208
|
+
if (throttleIntervalId !== null) {
|
|
209
|
+
clearInterval(throttleIntervalId);
|
|
210
|
+
throttleIntervalId = null;
|
|
211
|
+
}
|
|
212
|
+
lastThrottleCheckTime = null;
|
|
213
|
+
throttleSetupDone = false;
|
|
214
|
+
throttleMeasurements.length = 0;
|
|
215
|
+
throttleInsertIndex = 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Checks if the tab was throttled at any point during the specified time window.
|
|
220
|
+
* Returns true if any timer measurement showed significant drift (throttling).
|
|
221
|
+
*
|
|
222
|
+
* @param startTime - The start timestamp of the window to check (DOMHighResTimeStamp)
|
|
223
|
+
* @param endTime - The end timestamp of the window to check (DOMHighResTimeStamp)
|
|
224
|
+
* @returns boolean - true if throttling was detected during the time window, false otherwise
|
|
225
|
+
*/
|
|
226
|
+
export function isTabThrottled(startTime, endTime) {
|
|
227
|
+
// Input validation
|
|
228
|
+
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || startTime >= endTime) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// No measurements available
|
|
233
|
+
if (throttleMeasurements.length === 0) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Check if any measurement within the time window indicates throttling
|
|
238
|
+
for (let i = 0; i < throttleMeasurements.length; i++) {
|
|
239
|
+
const measurement = throttleMeasurements[i];
|
|
240
|
+
if (measurement && measurement.time >= startTime && measurement.time <= endTime && measurement.isThrottled) {
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Gets detailed throttle information for debugging purposes.
|
|
249
|
+
* Returns all throttle measurements within the specified time window.
|
|
250
|
+
*
|
|
251
|
+
* @param startTime - The start timestamp of the window to check
|
|
252
|
+
* @param endTime - The end timestamp of the window to check
|
|
253
|
+
* @returns Array of throttle measurements within the time window
|
|
254
|
+
*/
|
|
255
|
+
export function getThrottleMeasurements(startTime, endTime) {
|
|
256
|
+
// Input validation
|
|
257
|
+
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || startTime >= endTime) {
|
|
258
|
+
return [];
|
|
259
|
+
}
|
|
260
|
+
return throttleMeasurements.filter(measurement => measurement && measurement.time >= startTime && measurement.time <= endTime);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Injects a fake throttle measurement for testing purposes.
|
|
265
|
+
* This allows integration tests to simulate throttling scenarios.
|
|
266
|
+
*
|
|
267
|
+
* @param measurement - The throttle measurement to inject
|
|
268
|
+
*/
|
|
269
|
+
export function __injectThrottleMeasurementForTesting(measurement) {
|
|
270
|
+
throttleMeasurements[throttleInsertIndex] = measurement;
|
|
271
|
+
throttleInsertIndex = (throttleInsertIndex + 1) % THROTTLE_BUFFER_SIZE;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Expose testing API on window for integration tests
|
|
275
|
+
if (typeof window !== 'undefined') {
|
|
276
|
+
window.__reactUfoHiddenTiming = {
|
|
277
|
+
__injectThrottleMeasurementForTesting
|
|
278
|
+
};
|
|
151
279
|
}
|
|
@@ -5,7 +5,7 @@ import { setUFOConfig } from '../config';
|
|
|
5
5
|
import { experimentalVC, sinkExperimentalHandler } from '../create-experimental-interaction-metrics-payload';
|
|
6
6
|
import { sinkExtraSearchPageInteractionHandler } from '../create-extra-search-page-interaction-payload';
|
|
7
7
|
import { setContextManager, UFOContextManager } from '../experience-trace-id-context/context-manager';
|
|
8
|
-
import { setupHiddenTimingCapture } from '../hidden-timing';
|
|
8
|
+
import { setupHiddenTimingCapture, setupThrottleDetection } from '../hidden-timing';
|
|
9
9
|
import { interactionExtraMetrics, postInteractionLog, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
|
|
10
10
|
import { getPerformanceObserver } from '../interactions-performance-observer';
|
|
11
11
|
import { initialiseMemoryObserver, initialisePressureObserver } from '../machine-utilisation';
|
|
@@ -163,6 +163,9 @@ export function init(analyticsWebClientAsync, config) {
|
|
|
163
163
|
}
|
|
164
164
|
setupHiddenTimingCapture();
|
|
165
165
|
startLighthouseObserver();
|
|
166
|
+
if (fg('platform_ufo_is_tab_throttled')) {
|
|
167
|
+
setupThrottleDetection();
|
|
168
|
+
}
|
|
166
169
|
initialized = true;
|
|
167
170
|
if (typeof PerformanceObserver !== 'undefined') {
|
|
168
171
|
const observer = getPerformanceObserver();
|
|
@@ -34,7 +34,7 @@ export default class VCCalculator_FY25_03 extends AbstractVCCalculatorBase {
|
|
|
34
34
|
if (!getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch).includes(entry.data.type)) {
|
|
35
35
|
return false;
|
|
36
36
|
}
|
|
37
|
-
if (entry.data.type === 'mutation:attribute:framework-routing'
|
|
37
|
+
if (entry.data.type === 'mutation:attribute:framework-routing') {
|
|
38
38
|
return false;
|
|
39
39
|
}
|
|
40
40
|
if (excludeSmartAnswersInSearch && isEntrySmartAnswersInSearch(entry) && !fg('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
1
|
import { isZeroDimensionRectangle } from '../utils/is-zero-dimension-rectangle';
|
|
3
2
|
function isValidEntry(entry) {
|
|
4
3
|
return entry.isIntersecting && entry.intersectionRect.width > 0 && entry.intersectionRect.height > 0;
|
|
@@ -31,29 +30,22 @@ export function createIntersectionObserver({
|
|
|
31
30
|
|
|
32
31
|
// override as display-contents mutation
|
|
33
32
|
if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute') {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (isRoutingMutation) {
|
|
42
|
-
return {
|
|
43
|
-
type: 'mutation:attribute:framework-routing',
|
|
44
|
-
mutationData: tagOrCallbackResult.mutationData
|
|
45
|
-
};
|
|
46
|
-
}
|
|
33
|
+
const {
|
|
34
|
+
attributeName,
|
|
35
|
+
oldValue,
|
|
36
|
+
newValue
|
|
37
|
+
} = tagOrCallbackResult.mutationData;
|
|
38
|
+
const isRoutingMutation = attributeName === 'style' && (!oldValue && newValue === 'display: none !important;' || oldValue === 'display: none !important;' && !newValue);
|
|
39
|
+
if (isRoutingMutation) {
|
|
47
40
|
return {
|
|
48
|
-
type: 'mutation:
|
|
49
|
-
mutationData: tagOrCallbackResult.mutationData
|
|
50
|
-
};
|
|
51
|
-
} else {
|
|
52
|
-
return {
|
|
53
|
-
type: 'mutation:display-contents-children-attribute',
|
|
41
|
+
type: 'mutation:attribute:framework-routing',
|
|
54
42
|
mutationData: tagOrCallbackResult.mutationData
|
|
55
43
|
};
|
|
56
44
|
}
|
|
45
|
+
return {
|
|
46
|
+
type: 'mutation:display-contents-children-attribute',
|
|
47
|
+
mutationData: tagOrCallbackResult.mutationData
|
|
48
|
+
};
|
|
57
49
|
}
|
|
58
50
|
return tagOrCallbackResult;
|
|
59
51
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _objectWithoutProperties from"@babel/runtime/helpers/objectWithoutProperties";import _asyncToGenerator from"@babel/runtime/helpers/asyncToGenerator";import _toConsumableArray from"@babel/runtime/helpers/toConsumableArray";import _slicedToArray from"@babel/runtime/helpers/slicedToArray";import _defineProperty from"@babel/runtime/helpers/defineProperty";var _excluded=["labelStack"];import _regeneratorRuntime from"@babel/runtime/regenerator";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;}}};}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;}}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;}function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable;})),t.push.apply(t,o);}return t;}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){_defineProperty(e,r,t[r]);}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r));});}return e;}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}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{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';var MAX_PAYLOAD_SIZE=230;function getUfoNameOverride(interaction){var ufoName=interaction.ufoName,apdex=interaction.apdex;try{var ufoNameOverrides=getUfoNameOverrides();if(ufoNameOverrides!=null){var metricKey=apdex.length>0?apdex[0].key:'';if(ufoNameOverrides[ufoName][metricKey]){return ufoNameOverrides[ufoName][metricKey];}}return ufoName;}catch(_unused){return ufoName;}}function getEarliestLegacyStopTime(interaction,labelStack){var earliestLegacyStopTime=null;interaction.apdex.forEach(function(a){var _a$labelStack;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&&(earliestLegacyStopTime!==null&&earliestLegacyStopTime!==void 0?earliestLegacyStopTime:a.stopTime)>=a.stopTime){earliestLegacyStopTime=a.stopTime;}});return earliestLegacyStopTime;}function getBm3EndTimeOrFallbackValue(interaction){var _getEarliestLegacySto;var labelStack=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[];var fallbackValue=arguments.length>2&&arguments[2]!==undefined?arguments[2]:interaction.end;if(interaction.type==='press'){return fallbackValue;}return(_getEarliestLegacySto=getEarliestLegacyStopTime(interaction,labelStack))!==null&&_getEarliestLegacySto!==void 0?_getEarliestLegacySto:fallbackValue;}function getPageVisibilityUpToTTI(interaction){var start=interaction.start;var bm3EndTimeOrInteractionEndTime=getBm3EndTimeOrFallbackValue(interaction);return getPageVisibilityState(start,bm3EndTimeOrInteractionEndTime);}function getMoreAccuratePageVisibilityUpToTTI(interaction){var old=getPageVisibilityUpToTTI(interaction);var tti=getEarliestLegacyStopTime(interaction,[]);if(!tti){return old;}var 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;var start=interaction.start,end=interaction.end;var config=getConfig();var interactionStatus=getInteractionStatus(interaction);var pageVisibilityUpToTTAI=getPageVisibilityUpToTTAI(interaction);var tti=(_interaction$apdex=interaction.apdex)===null||_interaction$apdex===void 0||(_interaction$apdex=_interaction$apdex[0])===null||_interaction$apdex===void 0?void 0:_interaction$apdex.stopTime;var ttai=interactionStatus.originalInteractionStatus==='SUCCEEDED'&&pageVisibilityUpToTTAI==='visible'?Math.round(end-start):undefined;var PPSMetricsAtTTI=tti!==undefined?getLighthouseMetrics({start:start,stop:tti}):null;var PPSMetricsAtTTAI=ttai!==undefined?getLighthouseMetrics({start: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 _objectSpread(_objectSpread({},PPSMetricsAtTTI),{},{'metrics@ttai':PPSMetricsAtTTAI});}}return{};}function getSSRProperties(type){var ssrPhases=getSSRPhaseSuccess(type);return _objectSpread(_objectSpread({'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{var config=getConfig();var type=interaction.type;var allowedTypes=['page_load'];var 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,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{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';var MAX_PAYLOAD_SIZE=230;function getUfoNameOverride(interaction){var ufoName=interaction.ufoName,apdex=interaction.apdex;try{var ufoNameOverrides=getUfoNameOverrides();if(ufoNameOverrides!=null){var metricKey=apdex.length>0?apdex[0].key:'';if(ufoNameOverrides[ufoName][metricKey]){return ufoNameOverrides[ufoName][metricKey];}}return ufoName;}catch(_unused){return ufoName;}}function getEarliestLegacyStopTime(interaction,labelStack){var earliestLegacyStopTime=null;interaction.apdex.forEach(function(a){var _a$labelStack;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&&(earliestLegacyStopTime!==null&&earliestLegacyStopTime!==void 0?earliestLegacyStopTime:a.stopTime)>=a.stopTime){earliestLegacyStopTime=a.stopTime;}});return earliestLegacyStopTime;}function getBm3EndTimeOrFallbackValue(interaction){var _getEarliestLegacySto;var labelStack=arguments.length>1&&arguments[1]!==undefined?arguments[1]:[];var fallbackValue=arguments.length>2&&arguments[2]!==undefined?arguments[2]:interaction.end;if(interaction.type==='press'){return fallbackValue;}return(_getEarliestLegacySto=getEarliestLegacyStopTime(interaction,labelStack))!==null&&_getEarliestLegacySto!==void 0?_getEarliestLegacySto:fallbackValue;}function getPageVisibilityUpToTTI(interaction){var start=interaction.start;var bm3EndTimeOrInteractionEndTime=getBm3EndTimeOrFallbackValue(interaction);return getPageVisibilityState(start,bm3EndTimeOrInteractionEndTime);}function getMoreAccuratePageVisibilityUpToTTI(interaction){var old=getPageVisibilityUpToTTI(interaction);var tti=getEarliestLegacyStopTime(interaction,[]);if(!tti){return old;}var 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;var start=interaction.start,end=interaction.end;var config=getConfig();var interactionStatus=getInteractionStatus(interaction);var pageVisibilityUpToTTAI=getPageVisibilityUpToTTAI(interaction);var tti=(_interaction$apdex=interaction.apdex)===null||_interaction$apdex===void 0||(_interaction$apdex=_interaction$apdex[0])===null||_interaction$apdex===void 0?void 0:_interaction$apdex.stopTime;var ttai=interactionStatus.originalInteractionStatus==='SUCCEEDED'&&pageVisibilityUpToTTAI==='visible'?Math.round(end-start):undefined;var PPSMetricsAtTTI=tti!==undefined?getLighthouseMetrics({start:start,stop:tti}):null;var PPSMetricsAtTTAI=ttai!==undefined?getLighthouseMetrics({start: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 _objectSpread(_objectSpread({},PPSMetricsAtTTI),{},{'metrics@ttai':PPSMetricsAtTTAI});}}return{};}function getSSRProperties(type){var ssrPhases=getSSRPhaseSuccess(type);return _objectSpread(_objectSpread({'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{var config=getConfig();var type=interaction.type;var allowedTypes=['page_load'];var 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{};}var reporter=new CHRReporter();var resourceTimings=filterResourceTimings(interaction.start,interaction.end);var assets=reporter.get(resourceTimings,assetsConfig,SSRDoneTime);if(assets){// Only add assets in case it exists
|
|
4
4
|
return{'event:assets':assets};}return{};}catch(_unused2){// Skip CHR in case of error
|
|
5
5
|
return{};}}function getTracingContextData(interaction){var trace=interaction.trace,start=interaction.start;var tracingContextData={};if(trace){tracingContextData={'ufo:tracingContext':{'X-B3-TraceId':trace.traceId,'X-B3-SpanId':trace.spanId,// eslint-disable-next-line compat/compat
|
|
@@ -9,13 +9,13 @@ try{return acc+item.cssRules.length;}catch(_unused3){return acc;}},0);var styleE
|
|
|
9
9
|
getInitialPageLoadSSRMetrics=function getInitialPageLoadSSRMetrics(){var _config$ssr;if(!isPageLoad){return{};}var config=getConfig();var SSRDoneTimeValue=getSSRDoneTimeValue(config);var SSRDoneTime=SSRDoneTimeValue!==undefined?{SSRDoneTime:Math.round(SSRDoneTimeValue)}:{};var isBM3ConfigSSRDoneAsFmp=interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp;var isUFOConfigSSRDoneAsFmp=interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp||!!(config!==null&&config!==void 0&&(_config$ssr=config.ssr)!==null&&_config$ssr!==void 0&&_config$ssr.getSSRDoneTime);if(!experimental&&(isBM3ConfigSSRDoneAsFmp||isUFOConfigSSRDoneAsFmp)&&SSRDoneTimeValue!==undefined){try{performance.mark("FMP",{startTime:SSRDoneTimeValue,detail:{devtools:{dataType:'marker'}}});}catch(_unused6){}}return _objectSpread(_objectSpread({},SSRDoneTime),{},{isBM3ConfigSSRDoneAsFmp:isBM3ConfigSSRDoneAsFmp,isUFOConfigSSRDoneAsFmp:isUFOConfigSSRDoneAsFmp});};pageLoadInteractionMetrics=getInitialPageLoadSSRMetrics();// Detailed payload. Page visibility = visible
|
|
10
10
|
getDetailedInteractionMetrics=function getDetailedInteractionMetrics(resourceTimings){if(experimental||window.__UFO_COMPACT_PAYLOAD__||!isDetailedPayload){return{};}var spans=[].concat(_toConsumableArray(interaction.spans),_toConsumableArray(atlaskitInteractionSpans));atlaskitInteractionSpans.length=0;var shouldInclude3pHolds=shouldUseRawDataThirdPartyBehavior(ufoName,type);var basePayload={errors:interaction.errors.map(function(_ref2){var labelStack=_ref2.labelStack,others=_objectWithoutProperties(_ref2,_excluded);return _objectSpread(_objectSpread({},others),{},{labelStack:labelStack&&optimizeLabelStack(labelStack,getReactUFOPayloadVersion(interaction.type))});}),holdActive:_toConsumableArray(interaction.holdActive.values()),redirects:optimizeRedirects(interaction.redirects,start),holdInfo:optimizeHoldInfo(experimental?interaction.holdExpInfo:interaction.holdInfo,start,getReactUFOPayloadVersion(interaction.type)),spans:optimizeSpans(spans,start,getReactUFOPayloadVersion(interaction.type)),requestInfo:optimizeRequestInfo(interaction.requestInfo,start,getReactUFOPayloadVersion(interaction.type)),customTimings:optimizeCustomTimings(interaction.customTimings,start),bundleEvalTimings:objectToArray(getBundleEvalTimings(start)),resourceTimings:objectToArray(resourceTimings)};// Include third-party holds when feature flag is active
|
|
11
11
|
if(shouldInclude3pHolds){var _interaction$hold3pIn;return _objectSpread(_objectSpread({},basePayload),{},{hold3pActive:interaction.hold3pActive?_toConsumableArray(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
|
-
getPageLoadDetailedInteractionMetrics=function getPageLoadDetailedInteractionMetrics(){var _config$ssr2,_config$ssr2$getSSRTi;if(!isPageLoad||!isDetailedPayload){return{};}var initialPageLoadExtraTimings=objectToArray(initialPageLoadExtraTiming.getTimings());var config=getConfig();var defaultSSRTimings=objectToArray(ssr.getSSRTimings());var ssrTimingsFromConfig=config===null||config===void 0||(_config$ssr2=config.ssr)===null||_config$ssr2===void 0||(_config$ssr2$getSSRTi=_config$ssr2.getSSRTimings)===null||_config$ssr2$getSSRTi===void 0?void 0:_config$ssr2$getSSRTi.call(_config$ssr2);return{initialPageLoadExtraTimings:initialPageLoadExtraTimings,SSRTimings:ssrTimingsFromConfig?[].concat(_toConsumableArray(ssrTimingsFromConfig),_toConsumableArray(defaultSSRTimings)):defaultSSRTimings};};if(experimental){expTTAI=getTTAI(interaction);}else{regularTTAI=getTTAI(interaction);}newUFOName=sanitizeUfoName(ufoName);resourceTimings=getResourceTimings(start,end);_context.t0=Promise;_context.t1=vcMetrics;if(_context.t1){_context.next=29;break;}_context.next=28;return getVCMetrics(interaction);case 28:_context.t1=_context.sent;case 29:_context.t2=_context.t1;_context.t3=experimental?getExperimentalVCMetrics(interaction):Promise.resolve(undefined);_context.t4=getPaintMetricsToLegacyFormat(type,end);_context.t5=getBatteryInfoToLegacyFormat();_context.t6=[_context.t2,_context.t3,_context.t4,_context.t5];_context.next=36;return _context.t0.all.call(_context.t0,_context.t6);case 36:_yield$Promise$all=_context.sent;_yield$Promise$all2=_slicedToArray(_yield$Promise$all,4);finalVCMetrics=_yield$Promise$all2[0];experimentalMetrics=_yield$Promise$all2[1];paintMetrics=_yield$Promise$all2[2];batteryInfo=_yield$Promise$all2[3];if(!experimental){addPerformanceMeasures(interaction.start,_toConsumableArray((finalVCMetrics===null||finalVCMetrics===void 0?void 0:finalVCMetrics['ufo:vc:rev'])||[]));}getReactHydrationStats=function getReactHydrationStats(){if(!hydration){return{};}return{hydration:hydration};};payload={actionSubject:'experience',action:'measured',eventType:'operational',source:'measured',tags:['observability'],attributes:{properties:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({// basic
|
|
12
|
+
getPageLoadDetailedInteractionMetrics=function getPageLoadDetailedInteractionMetrics(){var _config$ssr2,_config$ssr2$getSSRTi;if(!isPageLoad||!isDetailedPayload){return{};}var initialPageLoadExtraTimings=objectToArray(initialPageLoadExtraTiming.getTimings());var config=getConfig();var defaultSSRTimings=objectToArray(ssr.getSSRTimings());var ssrTimingsFromConfig=config===null||config===void 0||(_config$ssr2=config.ssr)===null||_config$ssr2===void 0||(_config$ssr2$getSSRTi=_config$ssr2.getSSRTimings)===null||_config$ssr2$getSSRTi===void 0?void 0:_config$ssr2$getSSRTi.call(_config$ssr2);return{initialPageLoadExtraTimings:initialPageLoadExtraTimings,SSRTimings:ssrTimingsFromConfig?[].concat(_toConsumableArray(ssrTimingsFromConfig),_toConsumableArray(defaultSSRTimings)):defaultSSRTimings};};if(experimental){expTTAI=getTTAI(interaction);}else{regularTTAI=getTTAI(interaction);}newUFOName=sanitizeUfoName(ufoName);resourceTimings=getResourceTimings(start,end);_context.t0=Promise;_context.t1=vcMetrics;if(_context.t1){_context.next=29;break;}_context.next=28;return getVCMetrics(interaction);case 28:_context.t1=_context.sent;case 29:_context.t2=_context.t1;_context.t3=experimental?getExperimentalVCMetrics(interaction):Promise.resolve(undefined);_context.t4=getPaintMetricsToLegacyFormat(type,end);_context.t5=getBatteryInfoToLegacyFormat();_context.t6=[_context.t2,_context.t3,_context.t4,_context.t5];_context.next=36;return _context.t0.all.call(_context.t0,_context.t6);case 36:_yield$Promise$all=_context.sent;_yield$Promise$all2=_slicedToArray(_yield$Promise$all,4);finalVCMetrics=_yield$Promise$all2[0];experimentalMetrics=_yield$Promise$all2[1];paintMetrics=_yield$Promise$all2[2];batteryInfo=_yield$Promise$all2[3];if(!experimental){addPerformanceMeasures(interaction.start,_toConsumableArray((finalVCMetrics===null||finalVCMetrics===void 0?void 0:finalVCMetrics['ufo:vc:rev'])||[]));}getReactHydrationStats=function getReactHydrationStats(){if(!hydration){return{};}return{hydration:hydration};};payload={actionSubject:'experience',action:'measured',eventType:'operational',source:'measured',tags:['observability'],attributes:{properties:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({// 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}:{}),fg('platform_ufo_browser_backgrounded_abort_timestamp')?{'ufo:pageVisibilityHiddenTimestamp':getEarliestHiddenTiming(interaction.start,interaction.end)}:{}),{},{'ufo:wasPageHiddenBeforeInit':getHasHiddenTimingBeforeSetup(),'ufo:isOpenedInBackground':isOpenedInBackground(interaction.type)},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:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId:interactionId,pageVisibilityAtTTI:pageVisibilityAtTTI,pageVisibilityAtTTAI:pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
|
|
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}:{}),fg('platform_ufo_browser_backgrounded_abort_timestamp')?{'ufo:pageVisibilityHiddenTimestamp':getEarliestHiddenTiming(interaction.start,interaction.end)}:{}),{},{'ufo:wasPageHiddenBeforeInit':getHasHiddenTimingBeforeSetup(),'ufo:isOpenedInBackground':isOpenedInBackground(interaction.type)},fg('platform_ufo_is_tab_throttled')?{'ufo:isTabThrottled':isTabThrottled(start,end)}:{}),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:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId:interactionId,pageVisibilityAtTTI:pageVisibilityAtTTI,pageVisibilityAtTTAI:pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
|
|
15
15
|
rate:rate,routeName:routeName,type:type,abortReason:abortReason,featureFlags:featureFlags,previousInteractionName:previousInteractionName,isPreviousInteractionAborted:isPreviousInteractionAborted,abortedByInteractionName:abortedByInteractionName,// performance
|
|
16
16
|
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:responsiveness}:{}),labelStack),pageLoadInteractionMetrics),getDetailedInteractionMetrics(resourceTimings)),getPageLoadDetailedInteractionMetrics()),getBm3TrackerTimings(interaction)),{},{'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI},unknownElementName?{unknownElementName:unknownElementName}:{}),unknownElementHierarchy?{unknownElementHierarchy:unknownElementHierarchy}:{}),'ufo:payloadTime':roundEpsilon(performance.now()-interactionPayloadStart)})}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if(fg('platform_ufo_enable_vc_raw_data')){size=getPayloadSize(payload.attributes.properties);vcRev=payload.attributes.properties['ufo:vc:rev'];rawData=vcRev.find(function(item){return item.revision==='raw-handler';});if(rawData){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(function(item){return 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
|
|
17
17
|
// we can add more fields as necessary
|
|
18
|
-
interactionMetricsFieldsToTrim=['requestInfo','featureFlags','resourceTimings'];properties=payload.attributes.properties;interactionMetrics=properties.interactionMetrics;if(!interactionMetrics){_context.next=74;break;}_iterator=_createForOfIteratorHelper(interactionMetricsFieldsToTrim);_context.prev=52;_iterator.s();case 54:if((_step=_iterator.n()).done){_context.next=66;break;}field=_step.value;if(!(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE)){_context.next=58;break;}return _context.abrupt("continue",64);case 58:interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push("interactionMetrics.".concat(field));properties['event:trimmedFields']=trimmedFields;case 64:_context.next=54;break;case 66:_context.next=71;break;case 68:_context.prev=68;_context.t7=_context["catch"](52);_iterator.e(_context.t7);case 71:_context.prev=71;_iterator.f();return _context.finish(71);case 74:return _context.abrupt("return",payload);case 75:case"end":return _context.stop();}},_callee,null,[[52,68,71,74]]);}));return _createInteractionMetricsPayload.apply(this,arguments);}export function createPayloads(_x6,_x7){return _createPayloads.apply(this,arguments);}function _createPayloads(){_createPayloads=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(interactionId,interaction){var ufoNameOverride,modifiedInteraction,payloads,isCriticalMetricsEnabled,vcMetrics,criticalMetricsPayloads,criticalPayloadCount,interactionMetricsPayload;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:ufoNameOverride=getUfoNameOverride(interaction);modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{ufoName:ufoNameOverride});payloads=[];isCriticalMetricsEnabled=fg('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
|
|
18
|
+
interactionMetricsFieldsToTrim=fg('ufo_remove_featureflags_from_trimmed_fields')?['requestInfo','resourceTimings']:['requestInfo','featureFlags','resourceTimings'];properties=payload.attributes.properties;interactionMetrics=properties.interactionMetrics;if(!interactionMetrics){_context.next=74;break;}_iterator=_createForOfIteratorHelper(interactionMetricsFieldsToTrim);_context.prev=52;_iterator.s();case 54:if((_step=_iterator.n()).done){_context.next=66;break;}field=_step.value;if(!(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE)){_context.next=58;break;}return _context.abrupt("continue",64);case 58:interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push("interactionMetrics.".concat(field));properties['event:trimmedFields']=trimmedFields;case 64:_context.next=54;break;case 66:_context.next=71;break;case 68:_context.prev=68;_context.t7=_context["catch"](52);_iterator.e(_context.t7);case 71:_context.prev=71;_iterator.f();return _context.finish(71);case 74:return _context.abrupt("return",payload);case 75:case"end":return _context.stop();}},_callee,null,[[52,68,71,74]]);}));return _createInteractionMetricsPayload.apply(this,arguments);}export function createPayloads(_x6,_x7){return _createPayloads.apply(this,arguments);}function _createPayloads(){_createPayloads=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(interactionId,interaction){var ufoNameOverride,modifiedInteraction,payloads,isCriticalMetricsEnabled,vcMetrics,criticalMetricsPayloads,criticalPayloadCount,interactionMetricsPayload;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:ufoNameOverride=getUfoNameOverride(interaction);modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{ufoName:ufoNameOverride});payloads=[];isCriticalMetricsEnabled=fg('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
|
|
19
19
|
_context2.next=6;return getVCMetrics(interaction);case 6:vcMetrics=_context2.sent;if(!isCriticalMetricsEnabled){_context2.next=13;break;}_context2.next=10;return createCriticalMetricsPayloads(interactionId,interaction,vcMetrics);case 10:_context2.t0=_context2.sent;_context2.next=14;break;case 13:_context2.t0=[];case 14:criticalMetricsPayloads=_context2.t0;payloads.push.apply(payloads,_toConsumableArray(criticalMetricsPayloads));criticalPayloadCount=isCriticalMetricsEnabled?criticalMetricsPayloads.length:undefined;_context2.next=19;return createInteractionMetricsPayload(modifiedInteraction,interactionId,undefined,criticalPayloadCount,vcMetrics);case 19:interactionMetricsPayload=_context2.sent;payloads.push(interactionMetricsPayload);return _context2.abrupt("return",payloads.filter(Boolean));case 22:case"end":return _context2.stop();}},_callee2);}));return _createPayloads.apply(this,arguments);}export function createExperimentalMetricsPayload(_x8,_x9){return _createExperimentalMetricsPayload.apply(this,arguments);}function _createExperimentalMetricsPayload(){_createExperimentalMetricsPayload=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(interactionId,interaction){var config,ufoName,rate,pageVisibilityState,result;return _regeneratorRuntime.wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:config=getConfig();if(config){_context3.next=3;break;}throw Error('UFO Configuration not provided');case 3:ufoName=sanitizeUfoName(interaction.ufoName);rate=getExperimentalInteractionRate(ufoName,interaction.type);if(coinflip(rate)){_context3.next=7;break;}return _context3.abrupt("return",null);case 7:pageVisibilityState=getPageVisibilityState(interaction.start,interaction.end);if(!(pageVisibilityState!=='visible')){_context3.next=10;break;}return _context3.abrupt("return",null);case 10:_context3.next=12;return createInteractionMetricsPayload(interaction,interactionId,true);case 12:result=_context3.sent;return _context3.abrupt("return",result);case 14:case"end":return _context3.stop();}},_callee3);}));return _createExperimentalMetricsPayload.apply(this,arguments);}export function createExtraSearchPageInteractionPayload(_x0,_x1){return _createExtraSearchPageInteractionPayload.apply(this,arguments);}function _createExtraSearchPageInteractionPayload(){_createExtraSearchPageInteractionPayload=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(interactionId,interaction){var SAIN_HOLD_NAMES,NAME_OVERRIDE,SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL,newInteractionId,newEnd,holdInfo,reactProfilerTimings,lastHold,isLastHoldSAIN,lastFilteredTime,filteredReactProfilerTimings,lastTiming,modifiedInteraction,payloads,vcMetrics,interactionMetricsPayload;return _regeneratorRuntime.wrap(function _callee4$(_context4){while(1)switch(_context4.prev=_context4.next){case 0:SAIN_HOLD_NAMES=['search-ai-dialog-visible-text-loading','search-ai-dialog-all-text-loading'];NAME_OVERRIDE='search-page-ignoring-smart-answers';SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL='search-page-smart-answers';newInteractionId="".concat(interactionId,"-ignoring-smart-answers");// Calculate a new end time which excludes SAIN holds
|
|
20
20
|
holdInfo=interaction.holdInfo,reactProfilerTimings=interaction.reactProfilerTimings;lastHold=holdInfo.at(-1);isLastHoldSAIN=Boolean(lastHold&&SAIN_HOLD_NAMES.includes(lastHold.name));// A new end time is only calculated if the last hold is a SAIN hold
|
|
21
21
|
if(isLastHoldSAIN){lastFilteredTime=null;filteredReactProfilerTimings=reactProfilerTimings.filter(function(timing){if(timing.commitTime===lastFilteredTime){return false;}var isTimingSmartAnswersInSearch=timing.labelStack.some(function(label){return label.name===SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL;});if(isTimingSmartAnswersInSearch){lastFilteredTime=timing.commitTime;return false;}return true;});lastTiming=filteredReactProfilerTimings.at(-1);if(lastTiming){newEnd=lastTiming.commitTime;}}modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{end:newEnd!==null&&newEnd!==void 0?newEnd:interaction.end,holdInfo:[],knownSegments:[],reactProfilerTimings:[],ufoName:NAME_OVERRIDE});payloads=[];_context4.next=12;return getVCMetrics(interaction,false,true);case 12:vcMetrics=_context4.sent;_context4.next=15;return createInteractionMetricsPayload(modifiedInteraction,newInteractionId,undefined,undefined,vcMetrics);case 15:interactionMetricsPayload=_context4.sent;payloads.push(interactionMetricsPayload);return _context4.abrupt("return",payloads.filter(Boolean));case 18:case"end":return _context4.stop();}},_callee4);}));return _createExtraSearchPageInteractionPayload.apply(this,arguments);}
|
|
@@ -151,4 +151,134 @@ export function getPageVisibilityState(start, end) {
|
|
|
151
151
|
hiddenState = timings[startIdx].hidden ? 'hidden' : 'visible';
|
|
152
152
|
}
|
|
153
153
|
return hiddenState;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Throttle detection configuration
|
|
157
|
+
// Expected interval for timer checks (in milliseconds)
|
|
158
|
+
var THROTTLE_CHECK_INTERVAL_MS = 1000;
|
|
159
|
+
// Threshold for considering a timer as throttled (50% drift tolerance)
|
|
160
|
+
var THROTTLE_DRIFT_THRESHOLD = 1.5;
|
|
161
|
+
// Maximum number of throttle measurements to store (circular buffer)
|
|
162
|
+
var THROTTLE_BUFFER_SIZE = 120;
|
|
163
|
+
// Circular buffer to store throttle measurements
|
|
164
|
+
var throttleMeasurements = [];
|
|
165
|
+
var throttleInsertIndex = 0;
|
|
166
|
+
var throttleIntervalId = null;
|
|
167
|
+
var lastThrottleCheckTime = null;
|
|
168
|
+
var throttleSetupDone = false;
|
|
169
|
+
function recordThrottleMeasurement(expectedElapsed, actualElapsed) {
|
|
170
|
+
var isThrottled = actualElapsed > expectedElapsed * THROTTLE_DRIFT_THRESHOLD;
|
|
171
|
+
throttleMeasurements[throttleInsertIndex] = {
|
|
172
|
+
time: performance.now(),
|
|
173
|
+
expectedElapsed: expectedElapsed,
|
|
174
|
+
actualElapsed: actualElapsed,
|
|
175
|
+
isThrottled: isThrottled
|
|
176
|
+
};
|
|
177
|
+
throttleInsertIndex = (throttleInsertIndex + 1) % THROTTLE_BUFFER_SIZE;
|
|
178
|
+
}
|
|
179
|
+
function throttleCheckCallback() {
|
|
180
|
+
var currentTime = performance.now();
|
|
181
|
+
if (lastThrottleCheckTime !== null) {
|
|
182
|
+
var actualElapsed = currentTime - lastThrottleCheckTime;
|
|
183
|
+
recordThrottleMeasurement(THROTTLE_CHECK_INTERVAL_MS, actualElapsed);
|
|
184
|
+
}
|
|
185
|
+
lastThrottleCheckTime = currentTime;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Sets up the throttle detection mechanism.
|
|
190
|
+
* This should be called early in the page lifecycle.
|
|
191
|
+
* Uses a periodic timer to detect browser throttling by measuring timer drift.
|
|
192
|
+
*/
|
|
193
|
+
export function setupThrottleDetection() {
|
|
194
|
+
if (throttleSetupDone) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
throttleSetupDone = true;
|
|
198
|
+
|
|
199
|
+
// Record the initial timestamp
|
|
200
|
+
lastThrottleCheckTime = performance.now();
|
|
201
|
+
|
|
202
|
+
// Start the periodic timer for throttle detection
|
|
203
|
+
throttleIntervalId = setInterval(throttleCheckCallback, THROTTLE_CHECK_INTERVAL_MS);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Stops the throttle detection mechanism.
|
|
208
|
+
* Useful for cleanup in tests or when the feature is no longer needed.
|
|
209
|
+
*/
|
|
210
|
+
export function stopThrottleDetection() {
|
|
211
|
+
if (throttleIntervalId !== null) {
|
|
212
|
+
clearInterval(throttleIntervalId);
|
|
213
|
+
throttleIntervalId = null;
|
|
214
|
+
}
|
|
215
|
+
lastThrottleCheckTime = null;
|
|
216
|
+
throttleSetupDone = false;
|
|
217
|
+
throttleMeasurements.length = 0;
|
|
218
|
+
throttleInsertIndex = 0;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Checks if the tab was throttled at any point during the specified time window.
|
|
223
|
+
* Returns true if any timer measurement showed significant drift (throttling).
|
|
224
|
+
*
|
|
225
|
+
* @param startTime - The start timestamp of the window to check (DOMHighResTimeStamp)
|
|
226
|
+
* @param endTime - The end timestamp of the window to check (DOMHighResTimeStamp)
|
|
227
|
+
* @returns boolean - true if throttling was detected during the time window, false otherwise
|
|
228
|
+
*/
|
|
229
|
+
export function isTabThrottled(startTime, endTime) {
|
|
230
|
+
// Input validation
|
|
231
|
+
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || startTime >= endTime) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// No measurements available
|
|
236
|
+
if (throttleMeasurements.length === 0) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Check if any measurement within the time window indicates throttling
|
|
241
|
+
for (var i = 0; i < throttleMeasurements.length; i++) {
|
|
242
|
+
var measurement = throttleMeasurements[i];
|
|
243
|
+
if (measurement && measurement.time >= startTime && measurement.time <= endTime && measurement.isThrottled) {
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Gets detailed throttle information for debugging purposes.
|
|
252
|
+
* Returns all throttle measurements within the specified time window.
|
|
253
|
+
*
|
|
254
|
+
* @param startTime - The start timestamp of the window to check
|
|
255
|
+
* @param endTime - The end timestamp of the window to check
|
|
256
|
+
* @returns Array of throttle measurements within the time window
|
|
257
|
+
*/
|
|
258
|
+
export function getThrottleMeasurements(startTime, endTime) {
|
|
259
|
+
// Input validation
|
|
260
|
+
if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || startTime >= endTime) {
|
|
261
|
+
return [];
|
|
262
|
+
}
|
|
263
|
+
return throttleMeasurements.filter(function (measurement) {
|
|
264
|
+
return measurement && measurement.time >= startTime && measurement.time <= endTime;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Injects a fake throttle measurement for testing purposes.
|
|
270
|
+
* This allows integration tests to simulate throttling scenarios.
|
|
271
|
+
*
|
|
272
|
+
* @param measurement - The throttle measurement to inject
|
|
273
|
+
*/
|
|
274
|
+
export function __injectThrottleMeasurementForTesting(measurement) {
|
|
275
|
+
throttleMeasurements[throttleInsertIndex] = measurement;
|
|
276
|
+
throttleInsertIndex = (throttleInsertIndex + 1) % THROTTLE_BUFFER_SIZE;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Expose testing API on window for integration tests
|
|
280
|
+
if (typeof window !== 'undefined') {
|
|
281
|
+
window.__reactUfoHiddenTiming = {
|
|
282
|
+
__injectThrottleMeasurementForTesting: __injectThrottleMeasurementForTesting
|
|
283
|
+
};
|
|
154
284
|
}
|
|
@@ -8,7 +8,7 @@ import { setUFOConfig } from '../config';
|
|
|
8
8
|
import { experimentalVC, sinkExperimentalHandler } from '../create-experimental-interaction-metrics-payload';
|
|
9
9
|
import { sinkExtraSearchPageInteractionHandler } from '../create-extra-search-page-interaction-payload';
|
|
10
10
|
import { setContextManager, UFOContextManager } from '../experience-trace-id-context/context-manager';
|
|
11
|
-
import { setupHiddenTimingCapture } from '../hidden-timing';
|
|
11
|
+
import { setupHiddenTimingCapture, setupThrottleDetection } from '../hidden-timing';
|
|
12
12
|
import { interactionExtraMetrics, postInteractionLog, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
|
|
13
13
|
import { getPerformanceObserver } from '../interactions-performance-observer';
|
|
14
14
|
import { initialiseMemoryObserver, initialisePressureObserver } from '../machine-utilisation';
|
|
@@ -178,6 +178,9 @@ export function init(analyticsWebClientAsync, config) {
|
|
|
178
178
|
}
|
|
179
179
|
setupHiddenTimingCapture();
|
|
180
180
|
startLighthouseObserver();
|
|
181
|
+
if (fg('platform_ufo_is_tab_throttled')) {
|
|
182
|
+
setupThrottleDetection();
|
|
183
|
+
}
|
|
181
184
|
initialized = true;
|
|
182
185
|
if (typeof PerformanceObserver !== 'undefined') {
|
|
183
186
|
var observer = getPerformanceObserver();
|
|
@@ -45,7 +45,7 @@ var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
|
|
|
45
45
|
if (!getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch).includes(entry.data.type)) {
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
|
-
if (entry.data.type === 'mutation:attribute:framework-routing'
|
|
48
|
+
if (entry.data.type === 'mutation:attribute:framework-routing') {
|
|
49
49
|
return false;
|
|
50
50
|
}
|
|
51
51
|
if (excludeSmartAnswersInSearch && isEntrySmartAnswersInSearch(entry) && !fg('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
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; } } }; }
|
|
2
2
|
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; } }
|
|
3
3
|
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; }
|
|
4
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
4
|
import { isZeroDimensionRectangle } from '../utils/is-zero-dimension-rectangle';
|
|
6
5
|
function isValidEntry(entry) {
|
|
7
6
|
return entry.isIntersecting && entry.intersectionRect.width > 0 && entry.intersectionRect.height > 0;
|
|
@@ -32,28 +31,21 @@ export function createIntersectionObserver(_ref) {
|
|
|
32
31
|
|
|
33
32
|
// override as display-contents mutation
|
|
34
33
|
if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute') {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (isRoutingMutation) {
|
|
42
|
-
return {
|
|
43
|
-
type: 'mutation:attribute:framework-routing',
|
|
44
|
-
mutationData: tagOrCallbackResult.mutationData
|
|
45
|
-
};
|
|
46
|
-
}
|
|
34
|
+
var _tagOrCallbackResult$ = tagOrCallbackResult.mutationData,
|
|
35
|
+
attributeName = _tagOrCallbackResult$.attributeName,
|
|
36
|
+
oldValue = _tagOrCallbackResult$.oldValue,
|
|
37
|
+
newValue = _tagOrCallbackResult$.newValue;
|
|
38
|
+
var isRoutingMutation = attributeName === 'style' && (!oldValue && newValue === 'display: none !important;' || oldValue === 'display: none !important;' && !newValue);
|
|
39
|
+
if (isRoutingMutation) {
|
|
47
40
|
return {
|
|
48
|
-
type: 'mutation:
|
|
49
|
-
mutationData: tagOrCallbackResult.mutationData
|
|
50
|
-
};
|
|
51
|
-
} else {
|
|
52
|
-
return {
|
|
53
|
-
type: 'mutation:display-contents-children-attribute',
|
|
41
|
+
type: 'mutation:attribute:framework-routing',
|
|
54
42
|
mutationData: tagOrCallbackResult.mutationData
|
|
55
43
|
};
|
|
56
44
|
}
|
|
45
|
+
return {
|
|
46
|
+
type: 'mutation:display-contents-children-attribute',
|
|
47
|
+
mutationData: tagOrCallbackResult.mutationData
|
|
48
|
+
};
|
|
57
49
|
}
|
|
58
50
|
return tagOrCallbackResult;
|
|
59
51
|
};
|
|
@@ -119,6 +119,7 @@ export type ReactUFOPayload = {
|
|
|
119
119
|
'ufo:pageVisibilityHiddenTimestamp'?: number;
|
|
120
120
|
'ufo:wasPageHiddenBeforeInit'?: boolean;
|
|
121
121
|
'ufo:isOpenedInBackground'?: boolean;
|
|
122
|
+
'ufo:isTabThrottled'?: boolean;
|
|
122
123
|
interactionMetrics: {
|
|
123
124
|
namePrefix: string;
|
|
124
125
|
segmentPrefix: string;
|
|
@@ -9,3 +9,45 @@ export declare function isOpenedInBackground(interactionType: InteractionType):
|
|
|
9
9
|
export declare function getHasHiddenTimingBeforeSetup(): boolean;
|
|
10
10
|
export declare function setupHiddenTimingCapture(): void;
|
|
11
11
|
export declare function getPageVisibilityState(start: number, end: number): PageVisibility;
|
|
12
|
+
export type ThrottleMeasurement = {
|
|
13
|
+
time: number;
|
|
14
|
+
expectedElapsed: number;
|
|
15
|
+
actualElapsed: number;
|
|
16
|
+
isThrottled: boolean;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Sets up the throttle detection mechanism.
|
|
20
|
+
* This should be called early in the page lifecycle.
|
|
21
|
+
* Uses a periodic timer to detect browser throttling by measuring timer drift.
|
|
22
|
+
*/
|
|
23
|
+
export declare function setupThrottleDetection(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Stops the throttle detection mechanism.
|
|
26
|
+
* Useful for cleanup in tests or when the feature is no longer needed.
|
|
27
|
+
*/
|
|
28
|
+
export declare function stopThrottleDetection(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Checks if the tab was throttled at any point during the specified time window.
|
|
31
|
+
* Returns true if any timer measurement showed significant drift (throttling).
|
|
32
|
+
*
|
|
33
|
+
* @param startTime - The start timestamp of the window to check (DOMHighResTimeStamp)
|
|
34
|
+
* @param endTime - The end timestamp of the window to check (DOMHighResTimeStamp)
|
|
35
|
+
* @returns boolean - true if throttling was detected during the time window, false otherwise
|
|
36
|
+
*/
|
|
37
|
+
export declare function isTabThrottled(startTime: number, endTime: number): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Gets detailed throttle information for debugging purposes.
|
|
40
|
+
* Returns all throttle measurements within the specified time window.
|
|
41
|
+
*
|
|
42
|
+
* @param startTime - The start timestamp of the window to check
|
|
43
|
+
* @param endTime - The end timestamp of the window to check
|
|
44
|
+
* @returns Array of throttle measurements within the time window
|
|
45
|
+
*/
|
|
46
|
+
export declare function getThrottleMeasurements(startTime: number, endTime: number): ThrottleMeasurement[];
|
|
47
|
+
/**
|
|
48
|
+
* Injects a fake throttle measurement for testing purposes.
|
|
49
|
+
* This allows integration tests to simulate throttling scenarios.
|
|
50
|
+
*
|
|
51
|
+
* @param measurement - The throttle measurement to inject
|
|
52
|
+
*/
|
|
53
|
+
export declare function __injectThrottleMeasurementForTesting(measurement: ThrottleMeasurement): void;
|
|
@@ -121,6 +121,7 @@ export type ReactUFOPayload = {
|
|
|
121
121
|
'ufo:pageVisibilityHiddenTimestamp'?: number;
|
|
122
122
|
'ufo:wasPageHiddenBeforeInit'?: boolean;
|
|
123
123
|
'ufo:isOpenedInBackground'?: boolean;
|
|
124
|
+
'ufo:isTabThrottled'?: boolean;
|
|
124
125
|
interactionMetrics: {
|
|
125
126
|
namePrefix: string;
|
|
126
127
|
segmentPrefix: string;
|
|
@@ -9,3 +9,45 @@ export declare function isOpenedInBackground(interactionType: InteractionType):
|
|
|
9
9
|
export declare function getHasHiddenTimingBeforeSetup(): boolean;
|
|
10
10
|
export declare function setupHiddenTimingCapture(): void;
|
|
11
11
|
export declare function getPageVisibilityState(start: number, end: number): PageVisibility;
|
|
12
|
+
export type ThrottleMeasurement = {
|
|
13
|
+
time: number;
|
|
14
|
+
expectedElapsed: number;
|
|
15
|
+
actualElapsed: number;
|
|
16
|
+
isThrottled: boolean;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Sets up the throttle detection mechanism.
|
|
20
|
+
* This should be called early in the page lifecycle.
|
|
21
|
+
* Uses a periodic timer to detect browser throttling by measuring timer drift.
|
|
22
|
+
*/
|
|
23
|
+
export declare function setupThrottleDetection(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Stops the throttle detection mechanism.
|
|
26
|
+
* Useful for cleanup in tests or when the feature is no longer needed.
|
|
27
|
+
*/
|
|
28
|
+
export declare function stopThrottleDetection(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Checks if the tab was throttled at any point during the specified time window.
|
|
31
|
+
* Returns true if any timer measurement showed significant drift (throttling).
|
|
32
|
+
*
|
|
33
|
+
* @param startTime - The start timestamp of the window to check (DOMHighResTimeStamp)
|
|
34
|
+
* @param endTime - The end timestamp of the window to check (DOMHighResTimeStamp)
|
|
35
|
+
* @returns boolean - true if throttling was detected during the time window, false otherwise
|
|
36
|
+
*/
|
|
37
|
+
export declare function isTabThrottled(startTime: number, endTime: number): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Gets detailed throttle information for debugging purposes.
|
|
40
|
+
* Returns all throttle measurements within the specified time window.
|
|
41
|
+
*
|
|
42
|
+
* @param startTime - The start timestamp of the window to check
|
|
43
|
+
* @param endTime - The end timestamp of the window to check
|
|
44
|
+
* @returns Array of throttle measurements within the time window
|
|
45
|
+
*/
|
|
46
|
+
export declare function getThrottleMeasurements(startTime: number, endTime: number): ThrottleMeasurement[];
|
|
47
|
+
/**
|
|
48
|
+
* Injects a fake throttle measurement for testing purposes.
|
|
49
|
+
* This allows integration tests to simulate throttling scenarios.
|
|
50
|
+
*
|
|
51
|
+
* @param measurement - The throttle measurement to inject
|
|
52
|
+
*/
|
|
53
|
+
export declare function __injectThrottleMeasurementForTesting(measurement: ThrottleMeasurement): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/react-ufo",
|
|
3
|
-
"version": "5.1
|
|
3
|
+
"version": "5.2.1",
|
|
4
4
|
"description": "Parts of React UFO that are publicly available",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -101,6 +101,9 @@
|
|
|
101
101
|
"ufo_payload_use_idle_callback": {
|
|
102
102
|
"type": "boolean"
|
|
103
103
|
},
|
|
104
|
+
"platform_ufo_is_tab_throttled": {
|
|
105
|
+
"type": "boolean"
|
|
106
|
+
},
|
|
104
107
|
"platform_ufo_assets_check_for_nan": {
|
|
105
108
|
"type": "boolean"
|
|
106
109
|
},
|
|
@@ -179,9 +182,6 @@
|
|
|
179
182
|
"platform_mark_ufo_segment_first_load": {
|
|
180
183
|
"type": "boolean"
|
|
181
184
|
},
|
|
182
|
-
"platform_ufo_vc_ignore_display_none_mutations": {
|
|
183
|
-
"type": "boolean"
|
|
184
|
-
},
|
|
185
185
|
"platform_ufo_keypress_interaction_abort": {
|
|
186
186
|
"type": "boolean"
|
|
187
187
|
},
|
|
@@ -200,6 +200,9 @@
|
|
|
200
200
|
"rovo_search_page_ttvc_ignoring_smart_answers_fix": {
|
|
201
201
|
"type": "boolean"
|
|
202
202
|
},
|
|
203
|
+
"ufo_remove_featureflags_from_trimmed_fields": {
|
|
204
|
+
"type": "boolean"
|
|
205
|
+
},
|
|
203
206
|
"platform_ufo_enable_terminal_errors": {
|
|
204
207
|
"type": "boolean"
|
|
205
208
|
},
|