@firebase/performance 0.6.11 → 0.6.12-canary.01f36ea41
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/dist/esm/index.esm2017.js +164 -112
- package/dist/esm/index.esm2017.js.map +1 -1
- package/dist/esm/src/constants.d.ts +6 -0
- package/dist/esm/src/resources/trace.d.ts +3 -1
- package/dist/esm/src/resources/web_vitals.d.ts +25 -0
- package/dist/esm/src/services/api_service.d.ts +4 -0
- package/dist/esm/src/services/oob_resources_service.d.ts +5 -0
- package/dist/esm/src/services/perf_logger.d.ts +1 -0
- package/dist/esm/src/services/transport_service.d.ts +5 -0
- package/dist/index.cjs.js +164 -112
- package/dist/index.cjs.js.map +1 -1
- package/dist/src/constants.d.ts +6 -0
- package/dist/src/resources/trace.d.ts +3 -1
- package/dist/src/resources/web_vitals.d.ts +25 -0
- package/dist/src/services/api_service.d.ts +4 -0
- package/dist/src/services/oob_resources_service.d.ts +5 -0
- package/dist/src/services/perf_logger.d.ts +1 -0
- package/dist/src/services/transport_service.d.ts +5 -0
- package/package.json +10 -9
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ErrorFactory, areCookiesEnabled, isIndexedDBAvailable, validateIndexedDBOpenable, getModularInstance, deepEqual } from '@firebase/util';
|
|
2
2
|
import { Logger, LogLevel } from '@firebase/logger';
|
|
3
|
+
import { onLCP, onINP, onCLS } from 'web-vitals/attribution';
|
|
3
4
|
import { _getProvider, getApp, _registerComponent, registerVersion } from '@firebase/app';
|
|
4
5
|
import { Component } from '@firebase/component';
|
|
5
6
|
import '@firebase/installations';
|
|
6
7
|
|
|
7
8
|
const name = "@firebase/performance";
|
|
8
|
-
const version = "0.6.
|
|
9
|
+
const version = "0.6.12-canary.01f36ea41";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @license
|
|
@@ -35,6 +36,12 @@ const OOB_TRACE_PAGE_LOAD_PREFIX = '_wt_';
|
|
|
35
36
|
const FIRST_PAINT_COUNTER_NAME = '_fp';
|
|
36
37
|
const FIRST_CONTENTFUL_PAINT_COUNTER_NAME = '_fcp';
|
|
37
38
|
const FIRST_INPUT_DELAY_COUNTER_NAME = '_fid';
|
|
39
|
+
const LARGEST_CONTENTFUL_PAINT_METRIC_NAME = '_lcp';
|
|
40
|
+
const LARGEST_CONTENTFUL_PAINT_ATTRIBUTE_NAME = 'lcp_element';
|
|
41
|
+
const INTERACTION_TO_NEXT_PAINT_METRIC_NAME = '_inp';
|
|
42
|
+
const INTERACTION_TO_NEXT_PAINT_ATTRIBUTE_NAME = 'inp_interactionTarget';
|
|
43
|
+
const CUMULATIVE_LAYOUT_SHIFT_METRIC_NAME = '_cls';
|
|
44
|
+
const CUMULATIVE_LAYOUT_SHIFT_ATTRIBUTE_NAME = 'cls_largestShiftTarget';
|
|
38
45
|
const CONFIG_LOCAL_STORAGE_KEY = '@firebase/performance/config';
|
|
39
46
|
const CONFIG_EXPIRY_LOCAL_STORAGE_KEY = '@firebase/performance/configexpire';
|
|
40
47
|
const SERVICE = 'performance';
|
|
@@ -139,6 +146,9 @@ class Api {
|
|
|
139
146
|
if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {
|
|
140
147
|
this.onFirstInputDelay = window.perfMetrics.onFirstInputDelay;
|
|
141
148
|
}
|
|
149
|
+
this.onLCP = onLCP;
|
|
150
|
+
this.onINP = onINP;
|
|
151
|
+
this.onCLS = onCLS;
|
|
142
152
|
}
|
|
143
153
|
getUrl() {
|
|
144
154
|
// Do not capture the string query part of url.
|
|
@@ -692,9 +702,8 @@ function changeInitializationStatus() {
|
|
|
692
702
|
*/
|
|
693
703
|
const DEFAULT_SEND_INTERVAL_MS = 10 * 1000;
|
|
694
704
|
const INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;
|
|
695
|
-
// If end point does not work, the call will be tried for these many times.
|
|
696
|
-
const DEFAULT_REMAINING_TRIES = 3;
|
|
697
705
|
const MAX_EVENT_COUNT_PER_REQUEST = 1000;
|
|
706
|
+
const DEFAULT_REMAINING_TRIES = 3;
|
|
698
707
|
let remainingTries = DEFAULT_REMAINING_TRIES;
|
|
699
708
|
/* eslint-enable camelcase */
|
|
700
709
|
let queue = [];
|
|
@@ -711,11 +720,10 @@ function processQueue(timeOffset) {
|
|
|
711
720
|
if (remainingTries === 0) {
|
|
712
721
|
return;
|
|
713
722
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
return processQueue(DEFAULT_SEND_INTERVAL_MS);
|
|
723
|
+
if (queue.length > 0) {
|
|
724
|
+
dispatchQueueEvents();
|
|
717
725
|
}
|
|
718
|
-
|
|
726
|
+
processQueue(DEFAULT_SEND_INTERVAL_MS);
|
|
719
727
|
}, timeOffset);
|
|
720
728
|
}
|
|
721
729
|
function dispatchQueueEvents() {
|
|
@@ -739,7 +747,11 @@ function dispatchQueueEvents() {
|
|
|
739
747
|
log_event
|
|
740
748
|
};
|
|
741
749
|
/* eslint-enable camelcase */
|
|
742
|
-
|
|
750
|
+
postToFlEndpoint(data)
|
|
751
|
+
.then(() => {
|
|
752
|
+
remainingTries = DEFAULT_REMAINING_TRIES;
|
|
753
|
+
})
|
|
754
|
+
.catch(() => {
|
|
743
755
|
// If the request fails for some reason, add the events that were attempted
|
|
744
756
|
// back to the primary queue to retry later.
|
|
745
757
|
queue = [...staged, ...queue];
|
|
@@ -748,41 +760,16 @@ function dispatchQueueEvents() {
|
|
|
748
760
|
processQueue(DEFAULT_SEND_INTERVAL_MS);
|
|
749
761
|
});
|
|
750
762
|
}
|
|
751
|
-
function sendEventsToFl(data, staged) {
|
|
752
|
-
return postToFlEndpoint(data)
|
|
753
|
-
.then(res => {
|
|
754
|
-
if (!res.ok) {
|
|
755
|
-
consoleLogger.info('Call to Firebase backend failed.');
|
|
756
|
-
}
|
|
757
|
-
return res.json();
|
|
758
|
-
})
|
|
759
|
-
.then(res => {
|
|
760
|
-
// Find the next call wait time from the response.
|
|
761
|
-
const transportWait = Number(res.nextRequestWaitMillis);
|
|
762
|
-
let requestOffset = DEFAULT_SEND_INTERVAL_MS;
|
|
763
|
-
if (!isNaN(transportWait)) {
|
|
764
|
-
requestOffset = Math.max(transportWait, requestOffset);
|
|
765
|
-
}
|
|
766
|
-
// Delete request if response include RESPONSE_ACTION_UNKNOWN or DELETE_REQUEST action.
|
|
767
|
-
// Otherwise, retry request using normal scheduling if response include RETRY_REQUEST_LATER.
|
|
768
|
-
const logResponseDetails = res.logResponseDetails;
|
|
769
|
-
if (Array.isArray(logResponseDetails) &&
|
|
770
|
-
logResponseDetails.length > 0 &&
|
|
771
|
-
logResponseDetails[0].responseAction === 'RETRY_REQUEST_LATER') {
|
|
772
|
-
queue = [...staged, ...queue];
|
|
773
|
-
consoleLogger.info(`Retry transport request later.`);
|
|
774
|
-
}
|
|
775
|
-
remainingTries = DEFAULT_REMAINING_TRIES;
|
|
776
|
-
// Schedule the next process.
|
|
777
|
-
processQueue(requestOffset);
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
763
|
function postToFlEndpoint(data) {
|
|
781
764
|
const flTransportFullUrl = SettingsService.getInstance().getFlTransportFullUrl();
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
765
|
+
const body = JSON.stringify(data);
|
|
766
|
+
return navigator.sendBeacon && navigator.sendBeacon(flTransportFullUrl, body)
|
|
767
|
+
? Promise.resolve()
|
|
768
|
+
: fetch(flTransportFullUrl, {
|
|
769
|
+
method: 'POST',
|
|
770
|
+
body,
|
|
771
|
+
keepalive: true
|
|
772
|
+
}).then();
|
|
786
773
|
}
|
|
787
774
|
function addToQueue(evt) {
|
|
788
775
|
if (!evt.eventTime || !evt.message) {
|
|
@@ -803,6 +790,15 @@ serializer) {
|
|
|
803
790
|
});
|
|
804
791
|
};
|
|
805
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* Force flush the queued events. Useful at page unload time to ensure all
|
|
795
|
+
* events are uploaded.
|
|
796
|
+
*/
|
|
797
|
+
function flushQueuedEvents() {
|
|
798
|
+
while (queue.length > 0) {
|
|
799
|
+
dispatchQueueEvents();
|
|
800
|
+
}
|
|
801
|
+
}
|
|
806
802
|
|
|
807
803
|
/**
|
|
808
804
|
* @license
|
|
@@ -821,12 +817,16 @@ serializer) {
|
|
|
821
817
|
* limitations under the License.
|
|
822
818
|
*/
|
|
823
819
|
let logger;
|
|
820
|
+
//
|
|
824
821
|
// This method is not called before initialization.
|
|
825
822
|
function sendLog(resource, resourceType) {
|
|
826
823
|
if (!logger) {
|
|
827
|
-
logger =
|
|
824
|
+
logger = {
|
|
825
|
+
send: transportHandler(serializer),
|
|
826
|
+
flush: flushQueuedEvents
|
|
827
|
+
};
|
|
828
828
|
}
|
|
829
|
-
logger(resource, resourceType);
|
|
829
|
+
logger.send(resource, resourceType);
|
|
830
830
|
}
|
|
831
831
|
function logTrace(trace) {
|
|
832
832
|
const settingsService = SettingsService.getInstance();
|
|
@@ -842,10 +842,6 @@ function logTrace(trace) {
|
|
|
842
842
|
if (!Api.getInstance().requiredApisAvailable()) {
|
|
843
843
|
return;
|
|
844
844
|
}
|
|
845
|
-
// Only log the page load auto traces if page is visible.
|
|
846
|
-
if (trace.isAuto && getVisibilityState() !== VisibilityState.VISIBLE) {
|
|
847
|
-
return;
|
|
848
|
-
}
|
|
849
845
|
if (isPerfInitialized()) {
|
|
850
846
|
sendTraceLog(trace);
|
|
851
847
|
}
|
|
@@ -855,6 +851,11 @@ function logTrace(trace) {
|
|
|
855
851
|
getInitializationPromise(trace.performanceController).then(() => sendTraceLog(trace), () => sendTraceLog(trace));
|
|
856
852
|
}
|
|
857
853
|
}
|
|
854
|
+
function flushLogs() {
|
|
855
|
+
if (logger) {
|
|
856
|
+
logger.flush();
|
|
857
|
+
}
|
|
858
|
+
}
|
|
858
859
|
function sendTraceLog(trace) {
|
|
859
860
|
if (!getIid()) {
|
|
860
861
|
return;
|
|
@@ -864,7 +865,7 @@ function sendTraceLog(trace) {
|
|
|
864
865
|
!settingsService.logTraceAfterSampling) {
|
|
865
866
|
return;
|
|
866
867
|
}
|
|
867
|
-
|
|
868
|
+
sendLog(trace, 1 /* ResourceType.Trace */);
|
|
868
869
|
}
|
|
869
870
|
function logNetworkRequest(networkRequest) {
|
|
870
871
|
const settingsService = SettingsService.getInstance();
|
|
@@ -887,7 +888,7 @@ function logNetworkRequest(networkRequest) {
|
|
|
887
888
|
!settingsService.logNetworkAfterSampling) {
|
|
888
889
|
return;
|
|
889
890
|
}
|
|
890
|
-
|
|
891
|
+
sendLog(networkRequest, 0 /* ResourceType.NetworkRequest */);
|
|
891
892
|
}
|
|
892
893
|
function serializer(resource, resourceType) {
|
|
893
894
|
if (resourceType === 0 /* ResourceType.NetworkRequest */) {
|
|
@@ -947,6 +948,46 @@ function getApplicationInfo(firebaseApp) {
|
|
|
947
948
|
}
|
|
948
949
|
/* eslint-enable camelcase */
|
|
949
950
|
|
|
951
|
+
/**
|
|
952
|
+
* @license
|
|
953
|
+
* Copyright 2020 Google LLC
|
|
954
|
+
*
|
|
955
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
956
|
+
* you may not use this file except in compliance with the License.
|
|
957
|
+
* You may obtain a copy of the License at
|
|
958
|
+
*
|
|
959
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
960
|
+
*
|
|
961
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
962
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
963
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
964
|
+
* See the License for the specific language governing permissions and
|
|
965
|
+
* limitations under the License.
|
|
966
|
+
*/
|
|
967
|
+
function createNetworkRequestEntry(performanceController, entry) {
|
|
968
|
+
const performanceEntry = entry;
|
|
969
|
+
if (!performanceEntry || performanceEntry.responseStart === undefined) {
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
const timeOrigin = Api.getInstance().getTimeOrigin();
|
|
973
|
+
const startTimeUs = Math.floor((performanceEntry.startTime + timeOrigin) * 1000);
|
|
974
|
+
const timeToResponseInitiatedUs = performanceEntry.responseStart
|
|
975
|
+
? Math.floor((performanceEntry.responseStart - performanceEntry.startTime) * 1000)
|
|
976
|
+
: undefined;
|
|
977
|
+
const timeToResponseCompletedUs = Math.floor((performanceEntry.responseEnd - performanceEntry.startTime) * 1000);
|
|
978
|
+
// Remove the query params from logged network request url.
|
|
979
|
+
const url = performanceEntry.name && performanceEntry.name.split('?')[0];
|
|
980
|
+
const networkRequest = {
|
|
981
|
+
performanceController,
|
|
982
|
+
url,
|
|
983
|
+
responsePayloadBytes: performanceEntry.transferSize,
|
|
984
|
+
startTimeUs,
|
|
985
|
+
timeToResponseInitiatedUs,
|
|
986
|
+
timeToResponseCompletedUs
|
|
987
|
+
};
|
|
988
|
+
logNetworkRequest(networkRequest);
|
|
989
|
+
}
|
|
990
|
+
|
|
950
991
|
/**
|
|
951
992
|
* @license
|
|
952
993
|
* Copyright 2020 Google LLC
|
|
@@ -968,7 +1009,10 @@ const RESERVED_AUTO_PREFIX = '_';
|
|
|
968
1009
|
const oobMetrics = [
|
|
969
1010
|
FIRST_PAINT_COUNTER_NAME,
|
|
970
1011
|
FIRST_CONTENTFUL_PAINT_COUNTER_NAME,
|
|
971
|
-
FIRST_INPUT_DELAY_COUNTER_NAME
|
|
1012
|
+
FIRST_INPUT_DELAY_COUNTER_NAME,
|
|
1013
|
+
LARGEST_CONTENTFUL_PAINT_METRIC_NAME,
|
|
1014
|
+
CUMULATIVE_LAYOUT_SHIFT_METRIC_NAME,
|
|
1015
|
+
INTERACTION_TO_NEXT_PAINT_METRIC_NAME
|
|
972
1016
|
];
|
|
973
1017
|
/**
|
|
974
1018
|
* Returns true if the metric is custom and does not start with reserved prefix, or if
|
|
@@ -1207,7 +1251,7 @@ class Trace {
|
|
|
1207
1251
|
* @param paintTimings A array which contains paintTiming object of the page load
|
|
1208
1252
|
* @param firstInputDelay First input delay in millisec
|
|
1209
1253
|
*/
|
|
1210
|
-
static createOobTrace(performanceController, navigationTimings, paintTimings, firstInputDelay) {
|
|
1254
|
+
static createOobTrace(performanceController, navigationTimings, paintTimings, webVitalMetrics, firstInputDelay) {
|
|
1211
1255
|
const route = Api.getInstance().getUrl();
|
|
1212
1256
|
if (!route) {
|
|
1213
1257
|
return;
|
|
@@ -1237,7 +1281,21 @@ class Trace {
|
|
|
1237
1281
|
trace.putMetric(FIRST_INPUT_DELAY_COUNTER_NAME, Math.floor(firstInputDelay * 1000));
|
|
1238
1282
|
}
|
|
1239
1283
|
}
|
|
1284
|
+
this.addWebVitalMetric(trace, LARGEST_CONTENTFUL_PAINT_METRIC_NAME, LARGEST_CONTENTFUL_PAINT_ATTRIBUTE_NAME, webVitalMetrics.lcp);
|
|
1285
|
+
this.addWebVitalMetric(trace, CUMULATIVE_LAYOUT_SHIFT_METRIC_NAME, CUMULATIVE_LAYOUT_SHIFT_ATTRIBUTE_NAME, webVitalMetrics.cls);
|
|
1286
|
+
this.addWebVitalMetric(trace, INTERACTION_TO_NEXT_PAINT_METRIC_NAME, INTERACTION_TO_NEXT_PAINT_ATTRIBUTE_NAME, webVitalMetrics.inp);
|
|
1287
|
+
// Page load logs are sent at unload time and so should be logged and
|
|
1288
|
+
// flushed immediately.
|
|
1240
1289
|
logTrace(trace);
|
|
1290
|
+
flushLogs();
|
|
1291
|
+
}
|
|
1292
|
+
static addWebVitalMetric(trace, metricKey, attributeKey, metric) {
|
|
1293
|
+
if (metric) {
|
|
1294
|
+
trace.putMetric(metricKey, Math.floor(metric.value * 1000));
|
|
1295
|
+
if (metric.elementAttribution) {
|
|
1296
|
+
trace.putAttribute(attributeKey, metric.elementAttribution);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1241
1299
|
}
|
|
1242
1300
|
static createUserTimingTrace(performanceController, measureName) {
|
|
1243
1301
|
const trace = new Trace(performanceController, measureName, false, measureName);
|
|
@@ -1261,54 +1319,17 @@ class Trace {
|
|
|
1261
1319
|
* See the License for the specific language governing permissions and
|
|
1262
1320
|
* limitations under the License.
|
|
1263
1321
|
*/
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
return;
|
|
1268
|
-
}
|
|
1269
|
-
const timeOrigin = Api.getInstance().getTimeOrigin();
|
|
1270
|
-
const startTimeUs = Math.floor((performanceEntry.startTime + timeOrigin) * 1000);
|
|
1271
|
-
const timeToResponseInitiatedUs = performanceEntry.responseStart
|
|
1272
|
-
? Math.floor((performanceEntry.responseStart - performanceEntry.startTime) * 1000)
|
|
1273
|
-
: undefined;
|
|
1274
|
-
const timeToResponseCompletedUs = Math.floor((performanceEntry.responseEnd - performanceEntry.startTime) * 1000);
|
|
1275
|
-
// Remove the query params from logged network request url.
|
|
1276
|
-
const url = performanceEntry.name && performanceEntry.name.split('?')[0];
|
|
1277
|
-
const networkRequest = {
|
|
1278
|
-
performanceController,
|
|
1279
|
-
url,
|
|
1280
|
-
responsePayloadBytes: performanceEntry.transferSize,
|
|
1281
|
-
startTimeUs,
|
|
1282
|
-
timeToResponseInitiatedUs,
|
|
1283
|
-
timeToResponseCompletedUs
|
|
1284
|
-
};
|
|
1285
|
-
logNetworkRequest(networkRequest);
|
|
1286
|
-
}
|
|
1287
|
-
|
|
1288
|
-
/**
|
|
1289
|
-
* @license
|
|
1290
|
-
* Copyright 2020 Google LLC
|
|
1291
|
-
*
|
|
1292
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1293
|
-
* you may not use this file except in compliance with the License.
|
|
1294
|
-
* You may obtain a copy of the License at
|
|
1295
|
-
*
|
|
1296
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1297
|
-
*
|
|
1298
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
1299
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1300
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1301
|
-
* See the License for the specific language governing permissions and
|
|
1302
|
-
* limitations under the License.
|
|
1303
|
-
*/
|
|
1304
|
-
const FID_WAIT_TIME_MS = 5000;
|
|
1322
|
+
let webVitalMetrics = {};
|
|
1323
|
+
let sentPageLoadTrace = false;
|
|
1324
|
+
let firstInputDelay;
|
|
1305
1325
|
function setupOobResources(performanceController) {
|
|
1306
1326
|
// Do not initialize unless iid is available.
|
|
1307
1327
|
if (!getIid()) {
|
|
1308
1328
|
return;
|
|
1309
1329
|
}
|
|
1310
|
-
// The load event might not have fired yet, and that means performance
|
|
1311
|
-
// object has a duration of 0. The setup should run after
|
|
1330
|
+
// The load event might not have fired yet, and that means performance
|
|
1331
|
+
// navigation timing object has a duration of 0. The setup should run after
|
|
1332
|
+
// all current tasks in js queue.
|
|
1312
1333
|
setTimeout(() => setupOobTraces(performanceController), 0);
|
|
1313
1334
|
setTimeout(() => setupNetworkRequests(performanceController), 0);
|
|
1314
1335
|
setTimeout(() => setupUserTimingTraces(performanceController), 0);
|
|
@@ -1323,27 +1344,44 @@ function setupNetworkRequests(performanceController) {
|
|
|
1323
1344
|
}
|
|
1324
1345
|
function setupOobTraces(performanceController) {
|
|
1325
1346
|
const api = Api.getInstance();
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1347
|
+
// Better support for Safari
|
|
1348
|
+
if ('onpagehide' in window) {
|
|
1349
|
+
api.document.addEventListener('pagehide', () => sendOobTrace(performanceController));
|
|
1350
|
+
}
|
|
1351
|
+
else {
|
|
1352
|
+
api.document.addEventListener('unload', () => sendOobTrace(performanceController));
|
|
1353
|
+
}
|
|
1354
|
+
api.document.addEventListener('visibilitychange', () => {
|
|
1355
|
+
if (api.document.visibilityState === 'hidden') {
|
|
1356
|
+
sendOobTrace(performanceController);
|
|
1357
|
+
}
|
|
1358
|
+
});
|
|
1330
1359
|
if (api.onFirstInputDelay) {
|
|
1331
|
-
// If the fid call back is not called for certain time, continue without it.
|
|
1332
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1333
|
-
let timeoutId = setTimeout(() => {
|
|
1334
|
-
Trace.createOobTrace(performanceController, navigationTimings, paintTimings);
|
|
1335
|
-
timeoutId = undefined;
|
|
1336
|
-
}, FID_WAIT_TIME_MS);
|
|
1337
1360
|
api.onFirstInputDelay((fid) => {
|
|
1338
|
-
|
|
1339
|
-
clearTimeout(timeoutId);
|
|
1340
|
-
Trace.createOobTrace(performanceController, navigationTimings, paintTimings, fid);
|
|
1341
|
-
}
|
|
1361
|
+
firstInputDelay = fid;
|
|
1342
1362
|
});
|
|
1343
1363
|
}
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1364
|
+
api.onLCP((metric) => {
|
|
1365
|
+
var _a;
|
|
1366
|
+
webVitalMetrics.lcp = {
|
|
1367
|
+
value: metric.value,
|
|
1368
|
+
elementAttribution: (_a = metric.attribution) === null || _a === void 0 ? void 0 : _a.element
|
|
1369
|
+
};
|
|
1370
|
+
});
|
|
1371
|
+
api.onCLS((metric) => {
|
|
1372
|
+
var _a;
|
|
1373
|
+
webVitalMetrics.cls = {
|
|
1374
|
+
value: metric.value,
|
|
1375
|
+
elementAttribution: (_a = metric.attribution) === null || _a === void 0 ? void 0 : _a.largestShiftTarget
|
|
1376
|
+
};
|
|
1377
|
+
});
|
|
1378
|
+
api.onINP((metric) => {
|
|
1379
|
+
var _a;
|
|
1380
|
+
webVitalMetrics.inp = {
|
|
1381
|
+
value: metric.value,
|
|
1382
|
+
elementAttribution: (_a = metric.attribution) === null || _a === void 0 ? void 0 : _a.interactionTarget
|
|
1383
|
+
};
|
|
1384
|
+
});
|
|
1347
1385
|
}
|
|
1348
1386
|
function setupUserTimingTraces(performanceController) {
|
|
1349
1387
|
const api = Api.getInstance();
|
|
@@ -1357,13 +1395,27 @@ function setupUserTimingTraces(performanceController) {
|
|
|
1357
1395
|
}
|
|
1358
1396
|
function createUserTimingTrace(performanceController, measure) {
|
|
1359
1397
|
const measureName = measure.name;
|
|
1360
|
-
// Do not create a trace, if the user timing marks and measures are created by
|
|
1398
|
+
// Do not create a trace, if the user timing marks and measures are created by
|
|
1399
|
+
// the sdk itself.
|
|
1361
1400
|
if (measureName.substring(0, TRACE_MEASURE_PREFIX.length) ===
|
|
1362
1401
|
TRACE_MEASURE_PREFIX) {
|
|
1363
1402
|
return;
|
|
1364
1403
|
}
|
|
1365
1404
|
Trace.createUserTimingTrace(performanceController, measureName);
|
|
1366
1405
|
}
|
|
1406
|
+
function sendOobTrace(performanceController) {
|
|
1407
|
+
if (!sentPageLoadTrace) {
|
|
1408
|
+
sentPageLoadTrace = true;
|
|
1409
|
+
const api = Api.getInstance();
|
|
1410
|
+
const navigationTimings = api.getEntriesByType('navigation');
|
|
1411
|
+
const paintTimings = api.getEntriesByType('paint');
|
|
1412
|
+
// On page unload web vitals may be updated so queue the oob trace creation
|
|
1413
|
+
// so that these updates have time to be included.
|
|
1414
|
+
setTimeout(() => {
|
|
1415
|
+
Trace.createOobTrace(performanceController, navigationTimings, paintTimings, webVitalMetrics, firstInputDelay);
|
|
1416
|
+
}, 0);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1367
1419
|
|
|
1368
1420
|
/**
|
|
1369
1421
|
* @license
|