@newrelic/browser-agent 0.0.9 → 0.1.229
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/README.md +84 -207
- package/dist/cjs/cdn/lite.js +14 -0
- package/dist/cjs/cdn/polyfills/lite.js +4 -0
- package/dist/cjs/cdn/polyfills/pro.js +4 -0
- package/dist/cjs/cdn/polyfills/spa.js +4 -0
- package/dist/cjs/cdn/polyfills.js +14 -0
- package/dist/cjs/cdn/pro.js +19 -0
- package/dist/cjs/cdn/spa.js +19 -0
- package/dist/cjs/cdn/worker.js +16 -0
- package/dist/cjs/common/aggregate/aggregator.js +168 -0
- package/dist/cjs/common/browser-version/firefox-version.js +17 -0
- package/dist/cjs/common/browser-version/ios-version.js +18 -0
- package/dist/cjs/common/config/config.js +76 -0
- package/dist/cjs/common/config/state/configurable.js +32 -0
- package/dist/cjs/common/config/state/info.js +50 -0
- package/dist/cjs/common/config/state/init.js +86 -0
- package/dist/cjs/common/config/state/loader-config.js +28 -0
- package/dist/cjs/common/config/state/originals.js +9 -0
- package/dist/cjs/common/config/state/runtime.js +50 -0
- package/dist/cjs/common/constants/environment-variables.js +20 -0
- package/dist/cjs/common/context/shared-context.js +25 -0
- package/dist/cjs/common/deny-list/deny-list.js +108 -0
- package/dist/cjs/common/drain/drain.js +126 -0
- package/dist/cjs/common/event-emitter/contextual-ee.js +149 -0
- package/dist/cjs/common/event-emitter/handle.js +24 -0
- package/dist/cjs/common/event-emitter/register-handler.js +24 -0
- package/dist/cjs/common/event-listener/event-listener-opts.js +46 -0
- package/dist/cjs/common/harvest/harvest-scheduler.js +111 -0
- package/dist/cjs/common/harvest/harvest.js +236 -0
- package/dist/cjs/common/ids/id.js +30 -0
- package/dist/cjs/common/ids/unique-id.js +84 -0
- package/dist/cjs/common/metrics/framework-detection.js +72 -0
- package/dist/cjs/common/metrics/paint-metrics.js +13 -0
- package/dist/cjs/common/serialize/bel-serializer.js +89 -0
- package/dist/cjs/common/timing/nav-timing.js +77 -0
- package/dist/cjs/common/timing/now.js +15 -0
- package/dist/cjs/common/unload/eol.js +69 -0
- package/dist/cjs/common/url/clean-url.js +16 -0
- package/dist/cjs/common/url/encode.js +79 -0
- package/dist/cjs/common/url/location.js +14 -0
- package/dist/cjs/common/url/parse-url.js +66 -0
- package/dist/cjs/common/url/protocol.js +25 -0
- package/dist/cjs/common/util/console.js +17 -0
- package/dist/cjs/common/util/data-size.js +25 -0
- package/dist/cjs/common/util/feature-flags.js +42 -0
- package/dist/cjs/common/util/get-or-set.js +39 -0
- package/dist/cjs/common/util/global-scope.js +56 -0
- package/dist/cjs/common/util/map-own.js +24 -0
- package/dist/cjs/common/util/obfuscate.js +76 -0
- package/dist/cjs/common/util/reduce.js +22 -0
- package/dist/cjs/common/util/s-hash.js +19 -0
- package/dist/cjs/common/util/single.js +23 -0
- package/dist/cjs/common/util/stringify.js +47 -0
- package/dist/cjs/common/util/submit-data.js +99 -0
- package/dist/cjs/common/util/traverse.js +41 -0
- package/dist/cjs/common/util/user-agent.js +57 -0
- package/dist/cjs/common/window/load.js +19 -0
- package/dist/cjs/common/window/nreum.js +107 -0
- package/dist/cjs/common/window/page-visibility.js +28 -0
- package/dist/cjs/common/window/session-storage.js +42 -0
- package/dist/cjs/common/window/supports-performance-observer.js +15 -0
- package/dist/cjs/common/window/top-level-callers.js +23 -0
- package/dist/cjs/common/wrap/index.js +68 -0
- package/dist/cjs/common/wrap/wrap-events.js +105 -0
- package/dist/cjs/common/wrap/wrap-fetch.js +114 -0
- package/dist/cjs/common/wrap/wrap-function.js +269 -0
- package/dist/cjs/common/wrap/wrap-history.js +56 -0
- package/dist/cjs/common/wrap/wrap-jsonp.js +129 -0
- package/dist/cjs/common/wrap/wrap-mutation.js +61 -0
- package/dist/cjs/common/wrap/wrap-promise.js +160 -0
- package/dist/cjs/common/wrap/wrap-raf.js +55 -0
- package/dist/cjs/common/wrap/wrap-timer.js +70 -0
- package/dist/cjs/common/wrap/wrap-xhr.js +206 -0
- package/dist/cjs/features/ajax/aggregate/index.js +226 -0
- package/dist/cjs/features/ajax/constants.js +9 -0
- package/dist/cjs/features/ajax/index.js +12 -0
- package/dist/cjs/features/ajax/instrument/distributed-tracing.js +145 -0
- package/dist/cjs/features/ajax/instrument/index.js +338 -0
- package/dist/cjs/features/ajax/instrument/response-size.js +26 -0
- package/dist/cjs/features/jserrors/aggregate/canonical-function-name.js +18 -0
- package/dist/cjs/features/jserrors/aggregate/canonical-function-name.test.js +30 -0
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.js +216 -0
- package/dist/cjs/features/jserrors/aggregate/compute-stack-trace.test.js +257 -0
- package/dist/cjs/features/jserrors/aggregate/format-stack-trace.js +36 -0
- package/dist/cjs/features/jserrors/aggregate/format-stack-trace.test.js +39 -0
- package/dist/cjs/features/jserrors/aggregate/index.js +267 -0
- package/dist/cjs/features/jserrors/aggregate/string-hash-code.js +23 -0
- package/dist/cjs/features/jserrors/aggregate/string-hash-code.test.js +26 -0
- package/dist/cjs/features/jserrors/constants.js +11 -0
- package/dist/cjs/features/jserrors/index.js +12 -0
- package/dist/cjs/features/jserrors/instrument/debug.js +40 -0
- package/dist/cjs/features/jserrors/instrument/index.js +158 -0
- package/dist/cjs/features/metrics/aggregate/index.js +136 -0
- package/dist/cjs/features/metrics/constants.js +17 -0
- package/dist/cjs/features/metrics/index.js +12 -0
- package/dist/cjs/features/metrics/instrument/index.js +20 -0
- package/dist/cjs/features/metrics/instrument/workers-helper.js +121 -0
- package/dist/cjs/features/page_action/aggregate/index.js +112 -0
- package/dist/cjs/features/page_action/constants.js +9 -0
- package/dist/cjs/features/page_action/index.js +12 -0
- package/dist/cjs/features/page_action/instrument/index.js +21 -0
- package/dist/cjs/features/page_view_event/aggregate/index.js +133 -0
- package/dist/cjs/features/page_view_event/aggregate/initialized-features.js +39 -0
- package/dist/cjs/features/page_view_event/constants.js +15 -0
- package/dist/cjs/features/page_view_event/index.js +12 -0
- package/dist/cjs/features/page_view_event/instrument/index.js +38 -0
- package/dist/cjs/features/page_view_timing/aggregate/index.js +265 -0
- package/dist/cjs/features/page_view_timing/constants.js +9 -0
- package/dist/cjs/features/page_view_timing/first-paint.js +50 -0
- package/dist/cjs/features/page_view_timing/index.js +12 -0
- package/dist/cjs/features/page_view_timing/instrument/index.js +36 -0
- package/dist/cjs/features/page_view_timing/long-tasks.js +75 -0
- package/dist/cjs/features/session_trace/aggregate/index.js +375 -0
- package/dist/cjs/features/session_trace/constants.js +32 -0
- package/dist/cjs/features/session_trace/index.js +12 -0
- package/dist/cjs/features/session_trace/instrument/index.js +133 -0
- package/dist/cjs/features/spa/aggregate/index.js +684 -0
- package/dist/cjs/features/spa/aggregate/interaction-node.js +84 -0
- package/dist/cjs/features/spa/aggregate/interaction-node.test.js +16 -0
- package/dist/cjs/features/spa/aggregate/interaction.js +98 -0
- package/dist/cjs/features/spa/aggregate/serializer.js +147 -0
- package/dist/cjs/features/spa/constants.js +53 -0
- package/dist/cjs/features/spa/index.js +12 -0
- package/dist/cjs/features/spa/instrument/index.js +114 -0
- package/dist/cjs/features/utils/aggregate-base.js +13 -0
- package/dist/cjs/features/utils/feature-base.js +58 -0
- package/dist/cjs/features/utils/handler-cache.js +64 -0
- package/dist/cjs/features/utils/instrument-base.js +71 -0
- package/dist/cjs/features/utils/lazy-loader.js +44 -0
- package/dist/cjs/index.js +81 -58
- package/dist/cjs/loaders/agent.js +86 -0
- package/dist/cjs/loaders/api/api.js +109 -0
- package/dist/cjs/loaders/api/apiAsync.js +94 -0
- package/dist/cjs/loaders/browser-agent.js +29 -0
- package/dist/cjs/loaders/configure/configure.js +47 -0
- package/dist/cjs/loaders/features/enabled-features.js +19 -0
- package/dist/cjs/loaders/features/featureDependencies.js +32 -0
- package/dist/cjs/loaders/features/features.js +33 -0
- package/dist/cjs/loaders/micro-agent.js +93 -0
- package/dist/cjs/loaders/worker-agent.js +24 -0
- package/dist/esm/cdn/lite.js +12 -0
- package/dist/esm/cdn/polyfills/lite.js +7 -0
- package/dist/esm/cdn/polyfills/pro.js +7 -0
- package/dist/esm/cdn/polyfills/spa.js +7 -0
- package/dist/esm/cdn/polyfills.js +17 -0
- package/dist/esm/cdn/pro.js +17 -0
- package/dist/esm/cdn/spa.js +17 -0
- package/dist/esm/cdn/worker.js +14 -0
- package/dist/esm/common/aggregate/aggregator.js +161 -0
- package/dist/esm/common/browser-version/firefox-version.js +10 -0
- package/dist/esm/common/browser-version/ios-version.js +10 -0
- package/dist/esm/common/config/config.js +11 -0
- package/dist/esm/common/config/state/configurable.js +25 -0
- package/dist/esm/common/config/state/info.js +42 -0
- package/dist/esm/common/config/state/init.js +78 -0
- package/dist/esm/common/config/state/loader-config.js +21 -0
- package/dist/esm/common/config/state/originals.js +2 -0
- package/dist/esm/common/config/state/runtime.js +41 -0
- package/dist/esm/common/constants/environment-variables.js +11 -0
- package/dist/esm/common/context/shared-context.js +18 -0
- package/dist/esm/common/deny-list/deny-list.js +101 -0
- package/dist/esm/common/drain/drain.js +119 -0
- package/dist/esm/common/event-emitter/contextual-ee.js +142 -0
- package/dist/esm/common/event-emitter/handle.js +16 -0
- package/dist/esm/common/event-emitter/register-handler.js +19 -0
- package/dist/esm/common/event-listener/event-listener-opts.js +39 -0
- package/dist/esm/common/harvest/harvest-scheduler.js +105 -0
- package/dist/esm/common/harvest/harvest.js +228 -0
- package/dist/esm/common/ids/id.js +23 -0
- package/dist/esm/common/ids/unique-id.js +75 -0
- package/dist/esm/common/metrics/framework-detection.js +66 -0
- package/dist/esm/common/metrics/paint-metrics.js +6 -0
- package/dist/esm/common/serialize/bel-serializer.js +80 -0
- package/dist/esm/common/timing/nav-timing.js +67 -0
- package/dist/esm/common/timing/now.js +9 -0
- package/dist/esm/common/unload/eol.js +62 -0
- package/dist/esm/common/url/clean-url.js +10 -0
- package/dist/esm/common/url/encode.js +71 -0
- package/dist/esm/common/url/location.js +8 -0
- package/dist/esm/common/url/parse-url.js +60 -0
- package/dist/esm/common/url/protocol.js +17 -0
- package/dist/esm/common/util/console.js +11 -0
- package/dist/esm/common/util/data-size.js +19 -0
- package/dist/esm/common/util/feature-flags.js +33 -0
- package/dist/esm/common/util/get-or-set.js +33 -0
- package/dist/esm/common/util/global-scope.js +44 -0
- package/dist/esm/common/util/map-own.js +18 -0
- package/dist/esm/common/util/obfuscate.js +67 -0
- package/dist/esm/common/util/reduce.js +16 -0
- package/dist/esm/common/util/s-hash.js +13 -0
- package/dist/esm/common/util/single.js +16 -0
- package/dist/esm/common/util/stringify.js +42 -0
- package/dist/esm/common/util/submit-data.js +91 -0
- package/dist/esm/common/util/traverse.js +35 -0
- package/dist/esm/common/util/user-agent.js +48 -0
- package/dist/esm/common/window/load.js +12 -0
- package/dist/esm/common/window/nreum.js +91 -0
- package/dist/esm/common/window/page-visibility.js +23 -0
- package/dist/esm/common/window/session-storage.js +36 -0
- package/dist/esm/common/window/supports-performance-observer.js +9 -0
- package/dist/esm/common/window/top-level-callers.js +17 -0
- package/dist/esm/common/wrap/index.js +14 -0
- package/dist/esm/common/wrap/wrap-events.js +97 -0
- package/dist/esm/common/wrap/wrap-fetch.js +105 -0
- package/dist/esm/common/wrap/wrap-function.js +257 -0
- package/dist/esm/common/wrap/wrap-history.js +48 -0
- package/dist/esm/common/wrap/wrap-jsonp.js +122 -0
- package/dist/esm/common/wrap/wrap-mutation.js +54 -0
- package/dist/esm/common/wrap/wrap-promise.js +153 -0
- package/dist/esm/common/wrap/wrap-raf.js +48 -0
- package/dist/esm/common/wrap/wrap-timer.js +63 -0
- package/dist/esm/common/wrap/wrap-xhr.js +199 -0
- package/dist/esm/features/ajax/aggregate/index.js +218 -0
- package/dist/esm/features/ajax/constants.js +2 -0
- package/dist/esm/features/ajax/index.js +1 -0
- package/dist/esm/features/ajax/instrument/distributed-tracing.js +137 -0
- package/dist/esm/features/ajax/instrument/index.js +330 -0
- package/dist/esm/features/ajax/instrument/response-size.js +19 -0
- package/dist/esm/features/jserrors/aggregate/canonical-function-name.js +12 -0
- package/dist/esm/features/jserrors/aggregate/canonical-function-name.test.js +28 -0
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.js +209 -0
- package/dist/esm/features/jserrors/aggregate/compute-stack-trace.test.js +255 -0
- package/dist/esm/features/jserrors/aggregate/format-stack-trace.js +29 -0
- package/dist/esm/features/jserrors/aggregate/format-stack-trace.test.js +37 -0
- package/dist/esm/features/jserrors/aggregate/index.js +260 -0
- package/dist/esm/features/jserrors/aggregate/string-hash-code.js +17 -0
- package/dist/esm/features/jserrors/aggregate/string-hash-code.test.js +24 -0
- package/dist/esm/features/jserrors/constants.js +3 -0
- package/dist/esm/features/jserrors/index.js +1 -0
- package/dist/esm/features/jserrors/instrument/debug.js +38 -0
- package/dist/esm/features/jserrors/instrument/index.js +150 -0
- package/dist/esm/features/metrics/aggregate/index.js +129 -0
- package/dist/esm/features/metrics/constants.js +6 -0
- package/dist/esm/features/metrics/index.js +1 -0
- package/dist/esm/features/metrics/instrument/index.js +13 -0
- package/dist/esm/features/metrics/instrument/workers-helper.js +116 -0
- package/dist/esm/features/page_action/aggregate/index.js +105 -0
- package/dist/esm/features/page_action/constants.js +2 -0
- package/dist/esm/features/page_action/index.js +1 -0
- package/dist/esm/features/page_action/instrument/index.js +14 -0
- package/dist/esm/features/page_view_event/aggregate/index.js +124 -0
- package/dist/esm/features/page_view_event/aggregate/initialized-features.js +34 -0
- package/dist/esm/features/page_view_event/constants.js +5 -0
- package/dist/esm/features/page_view_event/index.js +1 -0
- package/dist/esm/features/page_view_event/instrument/index.js +29 -0
- package/dist/esm/features/page_view_timing/aggregate/index.js +258 -0
- package/dist/esm/features/page_view_timing/constants.js +2 -0
- package/dist/esm/features/page_view_timing/first-paint.js +43 -0
- package/dist/esm/features/page_view_timing/index.js +1 -0
- package/dist/esm/features/page_view_timing/instrument/index.js +28 -0
- package/dist/esm/features/page_view_timing/long-tasks.js +69 -0
- package/dist/esm/features/session_trace/aggregate/index.js +366 -0
- package/dist/esm/features/session_trace/constants.js +14 -0
- package/dist/esm/features/session_trace/index.js +1 -0
- package/dist/esm/features/session_trace/instrument/index.js +123 -0
- package/dist/esm/features/spa/aggregate/index.js +674 -0
- package/dist/esm/features/spa/aggregate/interaction-node.js +78 -0
- package/dist/esm/features/spa/aggregate/interaction-node.test.js +14 -0
- package/dist/esm/features/spa/aggregate/interaction.js +92 -0
- package/dist/esm/features/spa/aggregate/serializer.js +139 -0
- package/dist/esm/features/spa/constants.js +25 -0
- package/dist/esm/features/spa/index.js +1 -0
- package/dist/esm/features/spa/instrument/index.js +104 -0
- package/dist/esm/features/utils/aggregate-base.js +6 -0
- package/dist/esm/features/utils/feature-base.js +51 -0
- package/dist/esm/features/utils/handler-cache.js +57 -0
- package/dist/esm/features/utils/instrument-base.js +69 -0
- package/dist/esm/features/utils/lazy-loader.js +37 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/loaders/agent.js +77 -0
- package/dist/esm/loaders/api/api.js +104 -0
- package/dist/esm/loaders/api/apiAsync.js +88 -0
- package/dist/esm/loaders/browser-agent.js +23 -0
- package/dist/esm/loaders/configure/configure.js +41 -0
- package/dist/esm/loaders/features/enabled-features.js +13 -0
- package/dist/esm/loaders/features/featureDependencies.js +25 -0
- package/dist/esm/loaders/features/features.js +25 -0
- package/dist/esm/loaders/micro-agent.js +86 -0
- package/dist/esm/loaders/worker-agent.js +18 -0
- package/package.json +204 -71
- package/types.ts +221 -0
- package/dist/bundled/es5/index.js +0 -2
- package/dist/bundled/es5/index.js.map +0 -1
- package/dist/bundled/es6/index.js +0 -2
- package/dist/bundled/es6/index.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -19
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/types.d.ts +0 -94
- package/dist/cjs/types.js +0 -28
- package/dist/cjs/types.js.map +0 -1
- package/dist/cjs/utils/api/api.d.ts +0 -10
- package/dist/cjs/utils/api/api.js +0 -40
- package/dist/cjs/utils/api/api.js.map +0 -1
- package/dist/cjs/utils/config/build-configs.d.ts +0 -6
- package/dist/cjs/utils/config/build-configs.js +0 -68
- package/dist/cjs/utils/config/build-configs.js.map +0 -1
- package/dist/cjs/utils/features/features.d.ts +0 -5
- package/dist/cjs/utils/features/features.js +0 -14
- package/dist/cjs/utils/features/features.js.map +0 -1
- package/dist/cjs/utils/features/initialize.d.ts +0 -5
- package/dist/cjs/utils/features/initialize.js +0 -51
- package/dist/cjs/utils/features/initialize.js.map +0 -1
- package/dist/es/index.d.ts +0 -19
- package/dist/es/index.js +0 -55
- package/dist/es/index.js.map +0 -1
- package/dist/es/types.d.ts +0 -94
- package/dist/es/types.js +0 -24
- package/dist/es/types.js.map +0 -1
- package/dist/es/utils/api/api.d.ts +0 -10
- package/dist/es/utils/api/api.js +0 -36
- package/dist/es/utils/api/api.js.map +0 -1
- package/dist/es/utils/config/build-configs.d.ts +0 -6
- package/dist/es/utils/config/build-configs.js +0 -64
- package/dist/es/utils/config/build-configs.js.map +0 -1
- package/dist/es/utils/features/features.d.ts +0 -5
- package/dist/es/utils/features/features.js +0 -10
- package/dist/es/utils/features/features.js.map +0 -1
- package/dist/es/utils/features/initialize.d.ts +0 -5
- package/dist/es/utils/features/initialize.js +0 -24
- package/dist/es/utils/features/initialize.js.map +0 -1
- package/dist/umd/index.d.ts +0 -19
- package/dist/umd/index.js +0 -69
- package/dist/umd/index.js.map +0 -1
- package/dist/umd/types.d.ts +0 -94
- package/dist/umd/types.js +0 -38
- package/dist/umd/types.js.map +0 -1
- package/dist/umd/utils/api/api.d.ts +0 -10
- package/dist/umd/utils/api/api.js +0 -50
- package/dist/umd/utils/api/api.js.map +0 -1
- package/dist/umd/utils/config/build-configs.d.ts +0 -6
- package/dist/umd/utils/config/build-configs.js +0 -78
- package/dist/umd/utils/config/build-configs.js.map +0 -1
- package/dist/umd/utils/features/features.d.ts +0 -5
- package/dist/umd/utils/features/features.js +0 -24
- package/dist/umd/utils/features/features.js.map +0 -1
- package/dist/umd/utils/features/initialize.d.ts +0 -5
- package/dist/umd/utils/features/initialize.js +0 -63
- package/dist/umd/utils/features/initialize.js.map +0 -1
- package/dist/webpack-analysis.html +0 -38
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get an array of flags required by downstream (NR UI) based on the features initialized in this agent
|
|
5
|
+
* (aka what is running on the page).
|
|
6
|
+
* @param {String} agentId - the ID of the initialized agent on the page, mapping to the one under the global 'newrelic' object
|
|
7
|
+
* @returns {String[]} Up to 5 short strings corresponding to ingest mapping of features.
|
|
8
|
+
*/
|
|
9
|
+
export function getActivatedFeaturesFlags(agentId) {
|
|
10
|
+
const flagArr = [];
|
|
11
|
+
Object.keys(newrelic.initializedAgents[agentId].features).forEach(featName => {
|
|
12
|
+
switch (featName) {
|
|
13
|
+
case FEATURE_NAMES.ajax:
|
|
14
|
+
flagArr.push('xhr');
|
|
15
|
+
break;
|
|
16
|
+
case FEATURE_NAMES.jserrors:
|
|
17
|
+
flagArr.push('err');
|
|
18
|
+
break;
|
|
19
|
+
case FEATURE_NAMES.pageAction:
|
|
20
|
+
flagArr.push('ins');
|
|
21
|
+
break;
|
|
22
|
+
case FEATURE_NAMES.sessionTrace:
|
|
23
|
+
flagArr.push('stn');
|
|
24
|
+
break;
|
|
25
|
+
case FEATURE_NAMES.spa:
|
|
26
|
+
flagArr.push('spa');
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return flagArr;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Note: this module and the "af" param in src/features/page_view_event/aggregate/index.js can be removed in the future at such time
|
|
34
|
+
// that it's no longer being used. For the browser agent, this is an unused flag system.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Instrument as PageViewEvent } from './instrument/index';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { handle } from '../../../common/event-emitter/handle';
|
|
2
|
+
import { isiOS } from '../../../common/browser-version/ios-version';
|
|
3
|
+
import { InstrumentBase } from '../../utils/instrument-base';
|
|
4
|
+
import * as CONSTANTS from '../constants';
|
|
5
|
+
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
6
|
+
import { getRuntime } from '../../../common/config/config';
|
|
7
|
+
import { onDOMContentLoaded, onWindowLoad } from '../../../common/window/load';
|
|
8
|
+
import { now } from '../../../common/timing/now';
|
|
9
|
+
export class Instrument extends InstrumentBase {
|
|
10
|
+
static featureName = CONSTANTS.FEATURE_NAME;
|
|
11
|
+
constructor(agentIdentifier, aggregator, auto = true) {
|
|
12
|
+
super(agentIdentifier, aggregator, CONSTANTS.FEATURE_NAME, auto);
|
|
13
|
+
if ((typeof PerformanceNavigationTiming === 'undefined' || isiOS) && typeof PerformanceTiming !== 'undefined') {
|
|
14
|
+
// For majority browser versions in which PNT exists, we can get load timings later from the nav entry (in the aggregate portion). At minimum, PT should exist for main window.
|
|
15
|
+
// *cli Mar'23 - iOS 15.2 & 15.4 testing in Sauce still fails with onTTFB. Hence, all iOS will fallback to this for now. Unknown if this is similar in nature to iOS_below16 bug.
|
|
16
|
+
const agentRuntime = getRuntime(agentIdentifier);
|
|
17
|
+
agentRuntime[CONSTANTS.TTFB] = Math.max(Date.now() - agentRuntime.offset, 0);
|
|
18
|
+
onDOMContentLoaded(() => agentRuntime[CONSTANTS.FBTDC] = Math.max(now() - agentRuntime[CONSTANTS.TTFB], 0));
|
|
19
|
+
onWindowLoad(() => {
|
|
20
|
+
const timeNow = now();
|
|
21
|
+
agentRuntime[CONSTANTS.FBTWL] = Math.max(timeNow - agentRuntime[CONSTANTS.TTFB], 0);
|
|
22
|
+
handle('timing', ['load', timeNow], undefined, FEATURE_NAMES.pageViewTiming, this.ee);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Else, inference: inside worker or some other env where these events are irrelevant. They'll get filled in with 0s in RUM call.
|
|
26
|
+
|
|
27
|
+
this.importAggregator();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { onFCP, onFID, onLCP, onCLS, onINP } from 'web-vitals';
|
|
7
|
+
import { onFirstPaint } from '../first-paint';
|
|
8
|
+
import { onLongTask } from '../long-tasks';
|
|
9
|
+
import { iOS_below16 } from '../../../common/browser-version/ios-version';
|
|
10
|
+
import { nullable, numeric, getAddStringContext, addCustomAttributes } from '../../../common/serialize/bel-serializer';
|
|
11
|
+
import { mapOwn } from '../../../common/util/map-own';
|
|
12
|
+
import { HarvestScheduler } from '../../../common/harvest/harvest-scheduler';
|
|
13
|
+
import { registerHandler } from '../../../common/event-emitter/register-handler';
|
|
14
|
+
import { cleanURL } from '../../../common/url/clean-url';
|
|
15
|
+
import { handle } from '../../../common/event-emitter/handle';
|
|
16
|
+
import { getInfo, getConfigurationValue, getRuntime } from '../../../common/config/config';
|
|
17
|
+
import { AggregateBase } from '../../utils/aggregate-base';
|
|
18
|
+
import { FEATURE_NAME } from '../constants';
|
|
19
|
+
import { drain } from '../../../common/drain/drain';
|
|
20
|
+
import { FEATURE_NAMES } from '../../../loaders/features/features';
|
|
21
|
+
export class Aggregate extends AggregateBase {
|
|
22
|
+
static featureName = FEATURE_NAME;
|
|
23
|
+
constructor(agentIdentifier, aggregator) {
|
|
24
|
+
super(agentIdentifier, aggregator, FEATURE_NAME);
|
|
25
|
+
this.timings = [];
|
|
26
|
+
this.timingsSent = [];
|
|
27
|
+
this.curSessEndRecorded = false;
|
|
28
|
+
try {
|
|
29
|
+
// we (only) need to track cls state because it's attached to other timing events rather than reported on change...
|
|
30
|
+
this.clsSupported = PerformanceObserver.supportedEntryTypes.includes('layout-shift');
|
|
31
|
+
this.cls = 0;
|
|
32
|
+
} catch (e) {}
|
|
33
|
+
|
|
34
|
+
/*! This is the section that used to be in the loader portion: !*/
|
|
35
|
+
/* ------------------------------------------------------------ */
|
|
36
|
+
const pageStartedHidden = getRuntime(agentIdentifier).initHidden; // our attempt at recapturing initial vis state since this code runs post-load time
|
|
37
|
+
this.alreadySent = new Set(); // since we don't support timings on BFCache restores, this tracks and helps cap metrics that web-vitals report more than once
|
|
38
|
+
|
|
39
|
+
/* PerformancePaintTiming API - BFC is not yet supported. */
|
|
40
|
+
onFirstPaint(({
|
|
41
|
+
name,
|
|
42
|
+
value
|
|
43
|
+
}) => {
|
|
44
|
+
if (pageStartedHidden) return;
|
|
45
|
+
this.addTiming(name.toLowerCase(), Math.floor(value));
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
/* First Contentful Paint - As of WV v3, it still imperfectly tries to detect document vis state asap and isn't supposed to report if page starts hidden. */
|
|
49
|
+
if (iOS_below16) {
|
|
50
|
+
try {
|
|
51
|
+
if (!pageStartedHidden) {
|
|
52
|
+
// see ios-version.js for detail on this following bug case; tldr: buffered flag doesn't work but getEntriesByType does
|
|
53
|
+
const paintEntries = performance.getEntriesByType('paint');
|
|
54
|
+
paintEntries.forEach(entry => {
|
|
55
|
+
if (entry.name === 'first-contentful-paint') {
|
|
56
|
+
this.addTiming('fcp', Math.floor(entry.startTime));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
} catch (e) {}
|
|
61
|
+
} else {
|
|
62
|
+
onFCP(({
|
|
63
|
+
name,
|
|
64
|
+
value
|
|
65
|
+
}) => {
|
|
66
|
+
if (pageStartedHidden || this.alreadySent.has(name)) return;
|
|
67
|
+
this.alreadySent.add(name);
|
|
68
|
+
this.addTiming(name.toLowerCase(), value);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* First Input Delay (+"First Interaction") - As of WV v3, it still imperfectly tries to detect document vis state asap and isn't supposed to report if page starts hidden. */
|
|
73
|
+
onFID(({
|
|
74
|
+
name,
|
|
75
|
+
value,
|
|
76
|
+
entries
|
|
77
|
+
}) => {
|
|
78
|
+
if (pageStartedHidden || this.alreadySent.has(name)) return;
|
|
79
|
+
this.alreadySent.add(name);
|
|
80
|
+
|
|
81
|
+
// CWV will only report one (THE) first-input entry to us; fid isn't reported if there are no user interactions occurs before the *first* page hiding.
|
|
82
|
+
const fiEntry = entries[0];
|
|
83
|
+
const attributes = {
|
|
84
|
+
type: fiEntry.name,
|
|
85
|
+
fid: Math.round(value)
|
|
86
|
+
};
|
|
87
|
+
this.addConnectionAttributes(attributes);
|
|
88
|
+
this.addTiming('fi', Math.round(fiEntry.startTime), attributes);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
/* Largest Contentful Paint - As of WV v3, it still imperfectly tries to detect document vis state asap and isn't supposed to report if page starts hidden. */
|
|
92
|
+
onLCP(({
|
|
93
|
+
name,
|
|
94
|
+
value,
|
|
95
|
+
entries
|
|
96
|
+
}) => {
|
|
97
|
+
if (pageStartedHidden || this.alreadySent.has(name)) return;
|
|
98
|
+
this.alreadySent.add(name);
|
|
99
|
+
|
|
100
|
+
// CWV will only ever report one (THE) lcp entry to us; lcp is also only reported *once* on earlier(user interaction, page hidden).
|
|
101
|
+
const lcpEntry = entries[entries.length - 1]; // this looks weird if we only expect one, but this is how cwv-attribution gets it so to be sure...
|
|
102
|
+
const attrs = {
|
|
103
|
+
size: lcpEntry.size,
|
|
104
|
+
eid: lcpEntry.id
|
|
105
|
+
};
|
|
106
|
+
this.addConnectionAttributes(attrs);
|
|
107
|
+
if (lcpEntry.url) {
|
|
108
|
+
attrs['elUrl'] = cleanURL(lcpEntry.url);
|
|
109
|
+
}
|
|
110
|
+
if (lcpEntry.element && lcpEntry.element.tagName) {
|
|
111
|
+
attrs['elTag'] = lcpEntry.element.tagName;
|
|
112
|
+
}
|
|
113
|
+
this.addTiming(name.toLowerCase(), value, attrs);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
/* Cumulative Layout Shift - We don't have to limit this callback since cls is stored as a state and only sent as attribute on other timings. */
|
|
117
|
+
onCLS(({
|
|
118
|
+
value
|
|
119
|
+
}) => this.cls = value);
|
|
120
|
+
|
|
121
|
+
/* Interaction-to-Next-Paint */
|
|
122
|
+
onINP(({
|
|
123
|
+
name,
|
|
124
|
+
value,
|
|
125
|
+
id
|
|
126
|
+
}) => this.addTiming(name.toLowerCase(), value, {
|
|
127
|
+
metricId: id
|
|
128
|
+
}));
|
|
129
|
+
|
|
130
|
+
/* PerformanceLongTaskTiming API */
|
|
131
|
+
if (getConfigurationValue(this.agentIdentifier, 'page_view_timing.long_task') === true) {
|
|
132
|
+
onLongTask(({
|
|
133
|
+
name,
|
|
134
|
+
value,
|
|
135
|
+
info
|
|
136
|
+
}) => this.addTiming(name.toLowerCase(), value, info)); // lt context is passed as 'info'=attrs in the timing node
|
|
137
|
+
}
|
|
138
|
+
/* ------------------------------------End of ex-loader section */
|
|
139
|
+
|
|
140
|
+
/* It's important that CWV api, like "onLCP", is called before this scheduler is initialized. The reason is because they listen to the same
|
|
141
|
+
on vis change or pagehide events, and we'd want ex. onLCP to record the timing (win the race) before we try to send "final harvest". */
|
|
142
|
+
this.scheduler = new HarvestScheduler('events', {
|
|
143
|
+
onFinished: (...args) => this.onHarvestFinished(...args),
|
|
144
|
+
getPayload: (...args) => this.prepareHarvest(...args)
|
|
145
|
+
}, this);
|
|
146
|
+
registerHandler('timing', (name, value, attrs) => this.addTiming(name, value, attrs), this.featureName, this.ee); // notice CLS is added to all timings via 4th param
|
|
147
|
+
registerHandler('docHidden', msTimestamp => this.endCurrentSession(msTimestamp), this.featureName, this.ee);
|
|
148
|
+
registerHandler('winPagehide', msTimestamp => this.recordPageUnload(msTimestamp), this.featureName, this.ee);
|
|
149
|
+
const initialHarvestSeconds = getConfigurationValue(this.agentIdentifier, 'page_view_timing.initialHarvestSeconds') || 10;
|
|
150
|
+
const harvestTimeSeconds = getConfigurationValue(this.agentIdentifier, 'page_view_timing.harvestTimeSeconds') || 30;
|
|
151
|
+
// send initial data sooner, then start regular
|
|
152
|
+
this.ee.on(`drain-${this.featureName}`, () => {
|
|
153
|
+
this.scheduler.startTimer(harvestTimeSeconds, initialHarvestSeconds);
|
|
154
|
+
});
|
|
155
|
+
drain(this.agentIdentifier, this.featureName);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// takes an attributes object and appends connection attributes if available
|
|
159
|
+
addConnectionAttributes(attributes) {
|
|
160
|
+
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection; // to date, both window & worker shares the same support for connection
|
|
161
|
+
if (!connection) return;
|
|
162
|
+
if (connection.type) attributes['net-type'] = connection.type;
|
|
163
|
+
if (connection.effectiveType) attributes['net-etype'] = connection.effectiveType;
|
|
164
|
+
if (connection.rtt) attributes['net-rtt'] = connection.rtt;
|
|
165
|
+
if (connection.downlink) attributes['net-dlink'] = connection.downlink;
|
|
166
|
+
return attributes;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Add the time of _document visibilitychange to hidden_ to the next PVT harvest == NRDB pageHide attr.
|
|
171
|
+
* @param {number} timestamp
|
|
172
|
+
*/
|
|
173
|
+
endCurrentSession(timestamp) {
|
|
174
|
+
if (!this.curSessEndRecorded) {
|
|
175
|
+
// TO DO: stage 2 - we don't want to capture this timing twice on page navigating away, but it should run again if we return to page and away *again*
|
|
176
|
+
this.addTiming('pageHide', timestamp, null);
|
|
177
|
+
this.curSessEndRecorded = true;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Add the time of _window pagehide event_ firing to the next PVT harvest == NRDB windowUnload attr.
|
|
183
|
+
*/
|
|
184
|
+
recordPageUnload(timestamp) {
|
|
185
|
+
this.addTiming('unload', timestamp, null);
|
|
186
|
+
// Because window's pageHide commonly fires before vis change and the final harvest occurs on the earlier of the two, we also have to add that now or it won't make it into the last payload out.
|
|
187
|
+
this.endCurrentSession(timestamp);
|
|
188
|
+
}
|
|
189
|
+
addTiming(name, value, attrs) {
|
|
190
|
+
attrs = attrs || {};
|
|
191
|
+
|
|
192
|
+
// If CLS is supported, a cls value should exist and be reported, even at 0.
|
|
193
|
+
// *cli Mar'23 - At this time, it remains attached to all timings. See NEWRELIC-6143.
|
|
194
|
+
if (this.clsSupported) {
|
|
195
|
+
attrs['cls'] = this.cls;
|
|
196
|
+
}
|
|
197
|
+
this.timings.push({
|
|
198
|
+
name: name,
|
|
199
|
+
value: value,
|
|
200
|
+
attrs: attrs
|
|
201
|
+
});
|
|
202
|
+
handle('pvtAdded', [name, value, attrs], undefined, FEATURE_NAMES.sessionTrace, this.ee);
|
|
203
|
+
}
|
|
204
|
+
onHarvestFinished(result) {
|
|
205
|
+
if (result.retry && this.timingsSent.length > 0) {
|
|
206
|
+
for (var i = 0; i < this.timingsSent.length; i++) {
|
|
207
|
+
this.timings.push(this.timingsSent[i]);
|
|
208
|
+
}
|
|
209
|
+
this.timingsSent = [];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
appendGlobalCustomAttributes(timing) {
|
|
213
|
+
var timingAttributes = timing.attrs || {};
|
|
214
|
+
var customAttributes = getInfo(this.agentIdentifier).jsAttributes || {};
|
|
215
|
+
var reservedAttributes = ['size', 'eid', 'cls', 'type', 'fid', 'elTag', 'elUrl', 'net-type', 'net-etype', 'net-rtt', 'net-dlink'];
|
|
216
|
+
mapOwn(customAttributes, function (key, val) {
|
|
217
|
+
if (reservedAttributes.indexOf(key) < 0) {
|
|
218
|
+
timingAttributes[key] = val;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// serialize and return current timing data, clear and save current data for retry
|
|
224
|
+
prepareHarvest(options) {
|
|
225
|
+
if (this.timings.length === 0) return;
|
|
226
|
+
var payload = this.getPayload(this.timings);
|
|
227
|
+
if (options.retry) {
|
|
228
|
+
for (var i = 0; i < this.timings.length; i++) {
|
|
229
|
+
this.timingsSent.push(this.timings[i]);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
this.timings = [];
|
|
233
|
+
return {
|
|
234
|
+
body: {
|
|
235
|
+
e: payload
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// serialize array of timing data
|
|
241
|
+
getPayload(data) {
|
|
242
|
+
var addString = getAddStringContext(this.agentIdentifier);
|
|
243
|
+
var payload = 'bel.6;';
|
|
244
|
+
for (var i = 0; i < data.length; i++) {
|
|
245
|
+
var timing = data[i];
|
|
246
|
+
payload += 'e,';
|
|
247
|
+
payload += addString(timing.name) + ',';
|
|
248
|
+
payload += nullable(timing.value, numeric, false) + ',';
|
|
249
|
+
this.appendGlobalCustomAttributes(timing);
|
|
250
|
+
var attrParts = addCustomAttributes(timing.attrs, addString);
|
|
251
|
+
if (attrParts && attrParts.length > 0) {
|
|
252
|
+
payload += numeric(attrParts.length) + ';' + attrParts.join(';');
|
|
253
|
+
}
|
|
254
|
+
if (i + 1 < data.length) payload += ';';
|
|
255
|
+
}
|
|
256
|
+
return payload;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calls the `onReport` function when the 'first-paint' PerformancePaintTiming entry is observed.
|
|
3
|
+
* The argument supplied is an object similar to the Metric type used by web-vitals library.
|
|
4
|
+
*
|
|
5
|
+
* @param {Function} onReport - callback that accepts a `metric` object as the single parameter
|
|
6
|
+
*/
|
|
7
|
+
export const onFirstPaint = onReport => {
|
|
8
|
+
const handleEntries = entries => {
|
|
9
|
+
entries.forEach(entry => {
|
|
10
|
+
if (entry.name === 'first-paint') {
|
|
11
|
+
observer.disconnect();
|
|
12
|
+
|
|
13
|
+
/* Initial hidden state and pre-rendering not yet considered for first paint. See web-vitals onFCP for example. */
|
|
14
|
+
const metric = {
|
|
15
|
+
name: 'FP',
|
|
16
|
+
value: entry.startTime
|
|
17
|
+
};
|
|
18
|
+
onReport(metric);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
let observer;
|
|
23
|
+
try {
|
|
24
|
+
if (PerformanceObserver.supportedEntryTypes.includes('paint')) {
|
|
25
|
+
observer = new PerformanceObserver(list => {
|
|
26
|
+
// Delay by a microtask to workaround a bug in Safari where the
|
|
27
|
+
// callback is invoked immediately, rather than in a separate task.
|
|
28
|
+
// See: https://github.com/GoogleChrome/web-vitals/issues/277
|
|
29
|
+
Promise.resolve().then(() => {
|
|
30
|
+
handleEntries(list.getEntries());
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
observer.observe({
|
|
34
|
+
type: 'paint',
|
|
35
|
+
buffered: true
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
} catch (e) {
|
|
39
|
+
// Do nothing.
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* BFCache restore not yet considered for first paint. See web-vitals onFCP for example. */
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Instrument as PageViewTiming } from './instrument/index';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 New Relic Corporation. All rights reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { handle } from '../../../common/event-emitter/handle';
|
|
6
|
+
import { getRuntime } from '../../../common/config/config';
|
|
7
|
+
import { subscribeToVisibilityChange } from '../../../common/window/page-visibility';
|
|
8
|
+
import { windowAddEventListener } from '../../../common/event-listener/event-listener-opts';
|
|
9
|
+
import { now } from '../../../common/timing/now';
|
|
10
|
+
import { InstrumentBase } from '../../utils/instrument-base';
|
|
11
|
+
import { FEATURE_NAME } from '../constants';
|
|
12
|
+
import { isBrowserScope } from '../../../common/util/global-scope';
|
|
13
|
+
export class Instrument extends InstrumentBase {
|
|
14
|
+
static featureName = FEATURE_NAME;
|
|
15
|
+
constructor(agentIdentifier, aggregator, auto = true) {
|
|
16
|
+
super(agentIdentifier, aggregator, FEATURE_NAME, auto);
|
|
17
|
+
if (!isBrowserScope) return; // CWV is irrelevant outside web context
|
|
18
|
+
|
|
19
|
+
// Document visibility state becomes hidden; this should run as soon as possible in page life.
|
|
20
|
+
// While we try to replicate web-vital's visibilitywatcher logic in an effort to defer that library to post-pageload, this isn't perfect and doesn't consider prerendering.
|
|
21
|
+
getRuntime(agentIdentifier).initHidden = Boolean(document.visibilityState === 'hidden');
|
|
22
|
+
subscribeToVisibilityChange(() => handle('docHidden', [now()], undefined, FEATURE_NAME, this.ee), true);
|
|
23
|
+
|
|
24
|
+
// Window fires its pagehide event (typically on navigation--this occurrence is a *subset* of vis change); don't defer this unless it's guarantee it cannot happen before load(?)
|
|
25
|
+
windowAddEventListener('pagehide', () => handle('winPagehide', [now()], undefined, FEATURE_NAME, this.ee));
|
|
26
|
+
this.importAggregator();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { subscribeToEOL } from '../../common/unload/eol';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Calls the `onReport` function for every entry reported by the PerformanceLongTaskTiming API.
|
|
5
|
+
* The reported value is a `DOMHighResTimeStamp`.
|
|
6
|
+
*
|
|
7
|
+
* The callback is always called when the page's visibility state changes to hidden.
|
|
8
|
+
* As a result, the `onReport` function might be called multiple times during the same page load.
|
|
9
|
+
*
|
|
10
|
+
* @param {Function} onReport - callback that accepts a `metric` object as the single parameter
|
|
11
|
+
*/
|
|
12
|
+
export const onLongTask = onReport => {
|
|
13
|
+
const handleEntries = entries => {
|
|
14
|
+
entries.forEach(entry => {
|
|
15
|
+
const metric = {
|
|
16
|
+
name: 'LT',
|
|
17
|
+
value: entry.duration,
|
|
18
|
+
info: {
|
|
19
|
+
// this property deviates from CWV std interface but will hold the custom context to send to NRDB
|
|
20
|
+
ltFrame: entry.name,
|
|
21
|
+
// MDN: the browsing context or frame that can be attributed to the long task
|
|
22
|
+
ltStart: entry.startTime,
|
|
23
|
+
// MDN: a double representing the time (millisec) when the task started
|
|
24
|
+
ltCtr: entry.attribution[0].containerType // MDN: type of frame container: 'iframe', 'embed', or 'object' ... but this can also be 'window'
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
if (metric.info.ltCtr !== 'window') {
|
|
29
|
+
// the following properties are only of relevance & appended for html elements
|
|
30
|
+
Object.assign(metric.info, {
|
|
31
|
+
ltCtrSrc: entry.attribution[0].containerSrc,
|
|
32
|
+
// MDN: container's 'src' attribute
|
|
33
|
+
ltCtrId: entry.attribution[0].containerId,
|
|
34
|
+
// MDN: container's 'id' attribute
|
|
35
|
+
ltCtrName: entry.attribution[0].containerName // MDN: container's 'name' attribute
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
onReport(metric); // report every long task observed unconditionally
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
let observer;
|
|
44
|
+
try {
|
|
45
|
+
if (PerformanceObserver.supportedEntryTypes.includes('longtask')) {
|
|
46
|
+
observer = new PerformanceObserver(list => {
|
|
47
|
+
// Delay by a microtask to workaround a bug in Safari where the
|
|
48
|
+
// callback is invoked immediately, rather than in a separate task.
|
|
49
|
+
// See: https://github.com/GoogleChrome/web-vitals/issues/277
|
|
50
|
+
Promise.resolve().then(() => {
|
|
51
|
+
handleEntries(list.getEntries());
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
observer.observe({
|
|
55
|
+
type: 'longtask',
|
|
56
|
+
buffered: true
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
} catch (e) {
|
|
60
|
+
// Do nothing.
|
|
61
|
+
}
|
|
62
|
+
if (observer) {
|
|
63
|
+
subscribeToEOL(() => {
|
|
64
|
+
handleEntries(observer.takeRecords());
|
|
65
|
+
}, true); // this bool is a temp arg under staged BFCache work that runs the func under the new page session logic -- tb removed w/ the feature flag later
|
|
66
|
+
|
|
67
|
+
/* No work needed on BFCache restore for long task. */
|
|
68
|
+
}
|
|
69
|
+
};
|