From 6a95bcb4052a0273fc53f888dd958ea81f9c9a6c Mon Sep 17 00:00:00 2001 From: Jethro Nederhof Date: Thu, 6 Mar 2025 12:37:30 +1100 Subject: [PATCH] Bump web-vitals version From ~3 to ~4. Also make the metric interfaces optional in preparation for v5, which will remove the (deprecated in v4) `onFID` method. The FID metric is already optional in the [schema](https://iglucentral.com/?q=web_vitals), so there should be no breaking change here when this metric becomes unavailable. We assume if the user is using the library themselves they would be manually loading it and telling us not to via: - `loadVitalsScript: false` - `webVitalsSource` override So we don't consider this a breaking change unless a user is relying on us to load v3 and with this update we start loading v4 (which has some [breaking changes](https://github.com/GoogleChrome/web-vitals/blob/main/docs/upgrading-to-v4.md)). Users in this situation can set `webVitalsSource` to continue loading v3. When v5 is released, users can opt-in to using it by specifying a v5 source for `webVitalsSource`, which should work as expected with these changes until we update the plugin's default source to be v5. Closes #1411 --- ...feat-web-vitals-bump_2025-03-06-01-39.json | 10 ++++++++ common/config/rush/pnpm-lock.yaml | 10 ++++---- common/config/rush/repo-state.json | 2 +- .../browser-plugin-web-vitals/package.json | 2 +- .../browser-plugin-web-vitals/src/index.ts | 2 +- .../browser-plugin-web-vitals/src/types.ts | 24 ++++++++++++------- .../browser-plugin-web-vitals/src/utils.ts | 21 ++++++++-------- .../test/web-vitals.test.ts | 1 - 8 files changed, 44 insertions(+), 28 deletions(-) create mode 100644 common/changes/@snowplow/browser-plugin-web-vitals/feat-web-vitals-bump_2025-03-06-01-39.json diff --git a/common/changes/@snowplow/browser-plugin-web-vitals/feat-web-vitals-bump_2025-03-06-01-39.json b/common/changes/@snowplow/browser-plugin-web-vitals/feat-web-vitals-bump_2025-03-06-01-39.json new file mode 100644 index 000000000..ba3f32246 --- /dev/null +++ b/common/changes/@snowplow/browser-plugin-web-vitals/feat-web-vitals-bump_2025-03-06-01-39.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@snowplow/browser-plugin-web-vitals", + "comment": "Update default external library version to v4. Add compatibility for future v5, which deprecates the FID metric.", + "type": "none" + } + ], + "packageName": "@snowplow/browser-plugin-web-vitals" +} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 5c270a2a7..3fb2b15ca 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -1950,8 +1950,8 @@ importers: specifier: ^2.3.1 version: 2.8.1 web-vitals: - specifier: ~3.3.2 - version: 3.3.2 + specifier: ~4.2.4 + version: 4.2.4 devDependencies: '@ampproject/rollup-plugin-closure-compiler': specifier: ~0.27.0 @@ -8871,8 +8871,8 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} - web-vitals@3.3.2: - resolution: {integrity: sha512-qRkpmSeKfEWAzNhtX541xA8gCJ+pqCqBmUlDVkVDSCSYUvfvNqF+k9g8I+uyreRcDBdfiJrd0/aLbTy5ydo49Q==} + web-vitals@4.2.4: + resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} webdriver@8.39.0: resolution: {integrity: sha512-Kc3+SfiH4ufyrIht683VT2vnJocx0pfH8rYdyPvEh1b2OYewtFTHK36k9rBDHZiBmk6jcSXs4M2xeFgOuon9Lg==} @@ -17179,7 +17179,7 @@ snapshots: web-streams-polyfill@3.3.3: {} - web-vitals@3.3.2: {} + web-vitals@4.2.4: {} webdriver@8.39.0: dependencies: diff --git a/common/config/rush/repo-state.json b/common/config/rush/repo-state.json index a353e535b..033ec651f 100644 --- a/common/config/rush/repo-state.json +++ b/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "6f4a24fea0d73ed30b10703fd10b02f67710f7ba", + "pnpmShrinkwrapHash": "483ab7c144cc1201cfba40405c05ebf190586e79", "preferredVersionsHash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f" } diff --git a/plugins/browser-plugin-web-vitals/package.json b/plugins/browser-plugin-web-vitals/package.json index f79069cd0..0e651b274 100644 --- a/plugins/browser-plugin-web-vitals/package.json +++ b/plugins/browser-plugin-web-vitals/package.json @@ -25,7 +25,7 @@ "@snowplow/browser-tracker-core": "workspace:*", "@snowplow/tracker-core": "workspace:*", "tslib": "^2.3.1", - "web-vitals": "~3.3.2" + "web-vitals": "~4.2.4" }, "devDependencies": { "@ampproject/rollup-plugin-closure-compiler": "~0.27.0", diff --git a/plugins/browser-plugin-web-vitals/src/index.ts b/plugins/browser-plugin-web-vitals/src/index.ts index 600291bcb..e7e86f72f 100644 --- a/plugins/browser-plugin-web-vitals/src/index.ts +++ b/plugins/browser-plugin-web-vitals/src/index.ts @@ -4,7 +4,7 @@ import { WEB_VITALS_SCHEMA } from './schemata'; import { attachWebVitalsPageListeners, createWebVitalsScript, webVitalsListener } from './utils'; const _trackers: Record = {}; -const WEB_VITALS_SOURCE = 'https://unpkg.com/web-vitals@3/dist/web-vitals.iife.js'; +const WEB_VITALS_SOURCE = 'https://unpkg.com/web-vitals@4/dist/web-vitals.iife.js'; let listenersAttached = false; interface WebVitalsPluginOptions { diff --git a/plugins/browser-plugin-web-vitals/src/types.ts b/plugins/browser-plugin-web-vitals/src/types.ts index 681b8a70f..74b5ba003 100644 --- a/plugins/browser-plugin-web-vitals/src/types.ts +++ b/plugins/browser-plugin-web-vitals/src/types.ts @@ -1,12 +1,18 @@ -import type { ReportCallback, Metric, WebVitalsGlobal, onCLS, onLCP, onFID, onFCP, onINP, onTTFB } from 'web-vitals'; +import type { MetricType, Metric, onCLS, onLCP, onFID, onFCP, onINP, onTTFB } from 'web-vitals'; -export interface WebVitals extends WebVitalsGlobal { - onCLS: typeof onCLS; - onFID: typeof onFID; - onLCP: typeof onLCP; - onFCP: typeof onFCP; - onINP: typeof onINP; - onTTFB: typeof onTTFB; +export interface WebVitals { + onCLS?: typeof onCLS; + onFID?: typeof onFID; + onLCP?: typeof onLCP; + onFCP?: typeof onFCP; + onINP?: typeof onINP; + onTTFB?: typeof onTTFB; } -export { Metric, ReportCallback }; +declare global { + interface Window { + webVitals?: WebVitals; + } +} + +export { Metric, MetricType }; diff --git a/plugins/browser-plugin-web-vitals/src/utils.ts b/plugins/browser-plugin-web-vitals/src/utils.ts index 31916bfee..0434e378b 100644 --- a/plugins/browser-plugin-web-vitals/src/utils.ts +++ b/plugins/browser-plugin-web-vitals/src/utils.ts @@ -1,5 +1,5 @@ import { LOG } from '@snowplow/tracker-core'; -import { ReportCallback, WebVitals } from './types'; +import { MetricType } from './types'; /** * Attach page listeners to collect the Web Vitals values @@ -51,22 +51,23 @@ export function createWebVitalsScript(webVitalsSource: string) { * @return {void} */ export function webVitalsListener(webVitalsObject: Record) { - function addWebVitalsMeasurement(metricSchemaName: string): ReportCallback { + function addWebVitalsMeasurement(metricSchemaName: string): (arg: MetricType) => void { return (arg) => { webVitalsObject[metricSchemaName] = arg.value; webVitalsObject.navigationType = arg.navigationType; }; } - if (!window.webVitals) { + + const webVitals = window.webVitals; + if (!webVitals) { LOG.warn('The window.webVitals API is currently unavailable. web_vitals events will not be collected.'); return; } - const webVitals = window.webVitals as WebVitals; - webVitals.onCLS(addWebVitalsMeasurement('cls')); - webVitals.onFID(addWebVitalsMeasurement('fid')); - webVitals.onLCP(addWebVitalsMeasurement('lcp')); - webVitals.onFCP(addWebVitalsMeasurement('fcp')); - webVitals.onINP(addWebVitalsMeasurement('inp')); - webVitals.onTTFB(addWebVitalsMeasurement('ttfb')); + webVitals.onCLS?.(addWebVitalsMeasurement('cls')); + webVitals.onFID?.(addWebVitalsMeasurement('fid')); + webVitals.onLCP?.(addWebVitalsMeasurement('lcp')); + webVitals.onFCP?.(addWebVitalsMeasurement('fcp')); + webVitals.onINP?.(addWebVitalsMeasurement('inp')); + webVitals.onTTFB?.(addWebVitalsMeasurement('ttfb')); } diff --git a/plugins/browser-plugin-web-vitals/test/web-vitals.test.ts b/plugins/browser-plugin-web-vitals/test/web-vitals.test.ts index 8536d5b19..9a7691652 100644 --- a/plugins/browser-plugin-web-vitals/test/web-vitals.test.ts +++ b/plugins/browser-plugin-web-vitals/test/web-vitals.test.ts @@ -5,7 +5,6 @@ import { BrowserTracker } from '@snowplow/browser-tracker-core'; declare var jsdom: JSDOM; -// @ts-expect-error jsdom.window.webVitals = {}; describe('Web Vitals plugin', () => {