Update app and tooling

This commit is contained in:
Lawrence Chen 2026-01-29 17:36:26 -08:00
parent 3046531bdd
commit e620ec7349
4950 changed files with 2975120 additions and 10 deletions

2
node_modules/web-vitals/dist/getCLS.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
import { ReportHandler } from './types.js';
export declare const getCLS: (onReport: ReportHandler, reportAllChanges?: boolean) => void;

42
node_modules/web-vitals/dist/getCLS.js generated vendored Normal file
View file

@ -0,0 +1,42 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { initMetric } from './lib/initMetric.js';
import { observe } from './lib/observe.js';
import { onHidden } from './lib/onHidden.js';
import { bindReporter } from './lib/bindReporter.js';
export const getCLS = (onReport, reportAllChanges = false) => {
const metric = initMetric('CLS', 0);
let report;
const entryHandler = (entry) => {
// Only count layout shifts without recent user input.
if (!entry.hadRecentInput) {
metric.value += entry.value;
metric.entries.push(entry);
report();
}
};
const po = observe('layout-shift', entryHandler);
if (po) {
report = bindReporter(onReport, metric, po, reportAllChanges);
onHidden(({ isUnloading }) => {
po.takeRecords().map(entryHandler);
if (isUnloading) {
metric.isFinal = true;
}
report();
});
}
};

2
node_modules/web-vitals/dist/getFCP.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
import { ReportHandler } from './types.js';
export declare const getFCP: (onReport: ReportHandler) => void;

39
node_modules/web-vitals/dist/getFCP.js generated vendored Normal file
View file

@ -0,0 +1,39 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { bindReporter } from './lib/bindReporter.js';
import { getFirstHidden } from './lib/getFirstHidden.js';
import { initMetric } from './lib/initMetric.js';
import { observe } from './lib/observe.js';
export const getFCP = (onReport) => {
const metric = initMetric('FCP');
const firstHidden = getFirstHidden();
let report;
const entryHandler = (entry) => {
if (entry.name === 'first-contentful-paint') {
// Only report if the page wasn't hidden prior to the first paint.
if (entry.startTime < firstHidden.timeStamp) {
metric.value = entry.startTime;
metric.isFinal = true;
metric.entries.push(entry);
report();
}
}
};
const po = observe('paint', entryHandler);
if (po) {
report = bindReporter(onReport, metric, po);
}
};

14
node_modules/web-vitals/dist/getFID.d.ts generated vendored Normal file
View file

@ -0,0 +1,14 @@
import { ReportHandler } from './types.js';
interface FIDPolyfillCallback {
(value: number, event: Event): void;
}
interface FIDPolyfill {
onFirstInputDelay: (onReport: FIDPolyfillCallback) => void;
}
declare global {
interface Window {
perfMetrics: FIDPolyfill;
}
}
export declare const getFID: (onReport: ReportHandler) => void;
export {};

61
node_modules/web-vitals/dist/getFID.js generated vendored Normal file
View file

@ -0,0 +1,61 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { bindReporter } from './lib/bindReporter.js';
import { getFirstHidden } from './lib/getFirstHidden.js';
import { initMetric } from './lib/initMetric.js';
import { observe } from './lib/observe.js';
import { onHidden } from './lib/onHidden.js';
export const getFID = (onReport) => {
const metric = initMetric('FID');
const firstHidden = getFirstHidden();
const entryHandler = (entry) => {
// Only report if the page wasn't hidden prior to the first input.
if (entry.startTime < firstHidden.timeStamp) {
metric.value = entry.processingStart - entry.startTime;
metric.entries.push(entry);
metric.isFinal = true;
report();
}
};
const po = observe('first-input', entryHandler);
const report = bindReporter(onReport, metric, po);
if (po) {
onHidden(() => {
po.takeRecords().map(entryHandler);
po.disconnect();
}, true);
}
else {
if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {
window.perfMetrics.onFirstInputDelay((value, event) => {
// Only report if the page wasn't hidden prior to the first input.
if (event.timeStamp < firstHidden.timeStamp) {
metric.value = value;
metric.isFinal = true;
metric.entries = [{
entryType: 'first-input',
name: event.type,
target: event.target,
cancelable: event.cancelable,
startTime: event.timeStamp,
processingStart: event.timeStamp + value,
}];
report();
}
});
}
}
};

2
node_modules/web-vitals/dist/getLCP.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
import { ReportHandler } from './types.js';
export declare const getLCP: (onReport: ReportHandler, reportAllChanges?: boolean) => void;

54
node_modules/web-vitals/dist/getLCP.js generated vendored Normal file
View file

@ -0,0 +1,54 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { bindReporter } from './lib/bindReporter.js';
import { getFirstHidden } from './lib/getFirstHidden.js';
import { initMetric } from './lib/initMetric.js';
import { observe } from './lib/observe.js';
import { onHidden } from './lib/onHidden.js';
import { whenInput } from './lib/whenInput.js';
export const getLCP = (onReport, reportAllChanges = false) => {
const metric = initMetric('LCP');
const firstHidden = getFirstHidden();
let report;
const entryHandler = (entry) => {
// The startTime attribute returns the value of the renderTime if it is not 0,
// and the value of the loadTime otherwise.
const value = entry.startTime;
// If the page was hidden prior to paint time of the entry,
// ignore it and mark the metric as final, otherwise add the entry.
if (value < firstHidden.timeStamp) {
metric.value = value;
metric.entries.push(entry);
}
else {
metric.isFinal = true;
}
report();
};
const po = observe('largest-contentful-paint', entryHandler);
if (po) {
report = bindReporter(onReport, metric, po, reportAllChanges);
const onFinal = () => {
if (!metric.isFinal) {
po.takeRecords().map(entryHandler);
metric.isFinal = true;
report();
}
};
whenInput().then(onFinal);
onHidden(onFinal, true);
}
};

2
node_modules/web-vitals/dist/getTTFB.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
import { ReportHandler } from './types.js';
export declare const getTTFB: (onReport: ReportHandler) => void;

58
node_modules/web-vitals/dist/getTTFB.js generated vendored Normal file
View file

@ -0,0 +1,58 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { initMetric } from './lib/initMetric.js';
const afterLoad = (callback) => {
if (document.readyState === 'complete') {
// Queue a task so the callback runs after `loadEventEnd`.
setTimeout(callback, 0);
}
else {
// Use `pageshow` so the callback runs after `loadEventEnd`.
addEventListener('pageshow', callback);
}
};
const getNavigationEntryFromPerformanceTiming = () => {
// Really annoying that TypeScript errors when using `PerformanceTiming`.
const timing = performance.timing;
const navigationEntry = {
entryType: 'navigation',
startTime: 0,
};
for (const key in timing) {
if (key !== 'navigationStart' && key !== 'toJSON') {
navigationEntry[key] = Math.max(timing[key] - timing.navigationStart, 0);
}
}
return navigationEntry;
};
export const getTTFB = (onReport) => {
const metric = initMetric('TTFB');
afterLoad(() => {
try {
// Use the NavigationTiming L2 entry if available.
const navigationEntry = performance.getEntriesByType('navigation')[0] ||
getNavigationEntryFromPerformanceTiming();
metric.value = metric.delta =
navigationEntry.responseStart;
metric.entries = [navigationEntry];
metric.isFinal = true;
onReport(metric);
}
catch (error) {
// Do nothing.
}
});
};

6
node_modules/web-vitals/dist/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,6 @@
export { getCLS } from './getCLS.js';
export { getFCP } from './getFCP.js';
export { getFID } from './getFID.js';
export { getLCP } from './getLCP.js';
export { getTTFB } from './getTTFB.js';
export * from './types.js';

21
node_modules/web-vitals/dist/index.js generated vendored Normal file
View file

@ -0,0 +1,21 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { getCLS } from './getCLS.js';
export { getFCP } from './getFCP.js';
export { getFID } from './getFID.js';
export { getLCP } from './getLCP.js';
export { getTTFB } from './getTTFB.js';
export * from './types.js';

2
node_modules/web-vitals/dist/lib/bindReporter.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
import { Metric, ReportHandler } from '../types.js';
export declare const bindReporter: (callback: ReportHandler, metric: Metric, po: PerformanceObserver | undefined, observeAllUpdates?: boolean | undefined) => () => void;

38
node_modules/web-vitals/dist/lib/bindReporter.js generated vendored Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const bindReporter = (callback, metric, po, observeAllUpdates) => {
let prevValue;
return () => {
if (po && metric.isFinal) {
po.disconnect();
}
if (metric.value >= 0) {
if (observeAllUpdates ||
metric.isFinal ||
document.visibilityState === 'hidden') {
metric.delta = metric.value - (prevValue || 0);
// Report the metric if there's a non-zero delta, if the metric is
// final, or if no previous value exists (which can happen in the case
// of the document becoming hidden when the metric value is 0).
// See: https://github.com/GoogleChrome/web-vitals/issues/14
if (metric.delta || metric.isFinal || prevValue === undefined) {
callback(metric);
prevValue = metric.value;
}
}
}
};
};

View file

@ -0,0 +1,6 @@
/**
* Performantly generate a unique, 27-char string by combining the current
* timestamp with a 13-digit random number.
* @return {string}
*/
export declare const generateUniqueID: () => string;

23
node_modules/web-vitals/dist/lib/generateUniqueID.js generated vendored Normal file
View file

@ -0,0 +1,23 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Performantly generate a unique, 27-char string by combining the current
* timestamp with a 13-digit random number.
* @return {string}
*/
export const generateUniqueID = () => {
return `${Date.now()}-${Math.floor(Math.random() * (9e12 - 1)) + 1e12}`;
};

3
node_modules/web-vitals/dist/lib/getFirstHidden.d.ts generated vendored Normal file
View file

@ -0,0 +1,3 @@
export declare const getFirstHidden: () => {
readonly timeStamp: number;
};

33
node_modules/web-vitals/dist/lib/getFirstHidden.js generated vendored Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { onHidden } from './onHidden.js';
let firstHiddenTime;
export const getFirstHidden = () => {
if (firstHiddenTime === undefined) {
// If the document is hidden when this code runs, assume it was hidden
// since navigation start. This isn't a perfect heuristic, but it's the
// best we can do until an API is available to support querying past
// visibilityState.
firstHiddenTime = document.visibilityState === 'hidden' ? 0 : Infinity;
// Update the time if/when the document becomes hidden.
onHidden(({ timeStamp }) => firstHiddenTime = timeStamp, true);
}
return {
get timeStamp() {
return firstHiddenTime;
}
};
};

2
node_modules/web-vitals/dist/lib/initMetric.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
import { Metric } from '../types.js';
export declare const initMetric: (name: Metric['name'], value?: number) => Metric;

26
node_modules/web-vitals/dist/lib/initMetric.js generated vendored Normal file
View file

@ -0,0 +1,26 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { generateUniqueID } from './generateUniqueID.js';
export const initMetric = (name, value = -1) => {
return {
name,
value,
delta: 0,
entries: [],
id: generateUniqueID(),
isFinal: false
};
};

12
node_modules/web-vitals/dist/lib/observe.d.ts generated vendored Normal file
View file

@ -0,0 +1,12 @@
export interface PerformanceEntryHandler {
(entry: PerformanceEntry): void;
}
/**
* Takes a performance entry type and a callback function, and creates a
* `PerformanceObserver` instance that will observe the specified entry type
* with buffering enabled and call the callback _for each entry_.
*
* This function also feature-detects entry support and wraps the logic in a
* try/catch to avoid errors in unsupporting browsers.
*/
export declare const observe: (type: string, callback: PerformanceEntryHandler) => PerformanceObserver | undefined;

36
node_modules/web-vitals/dist/lib/observe.js generated vendored Normal file
View file

@ -0,0 +1,36 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Takes a performance entry type and a callback function, and creates a
* `PerformanceObserver` instance that will observe the specified entry type
* with buffering enabled and call the callback _for each entry_.
*
* This function also feature-detects entry support and wraps the logic in a
* try/catch to avoid errors in unsupporting browsers.
*/
export const observe = (type, callback) => {
try {
if (PerformanceObserver.supportedEntryTypes.includes(type)) {
const po = new PerformanceObserver((l) => l.getEntries().map(callback));
po.observe({ type, buffered: true });
return po;
}
}
catch (e) {
// Do nothing.
}
return;
};

7
node_modules/web-vitals/dist/lib/onHidden.d.ts generated vendored Normal file
View file

@ -0,0 +1,7 @@
export interface OnHiddenCallback {
({ timeStamp, isUnloading }: {
timeStamp: number;
isUnloading: boolean;
}): void;
}
export declare const onHidden: (cb: OnHiddenCallback, once?: boolean) => void;

38
node_modules/web-vitals/dist/lib/onHidden.js generated vendored Normal file
View file

@ -0,0 +1,38 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
let isUnloading = false;
let listenersAdded = false;
const onPageHide = (event) => {
isUnloading = !event.persisted;
};
const addListeners = () => {
addEventListener('pagehide', onPageHide);
// `beforeunload` is needed to fix this bug:
// https://bugs.chromium.org/p/chromium/issues/detail?id=987409
// eslint-disable-next-line @typescript-eslint/no-empty-function
addEventListener('beforeunload', () => { });
};
export const onHidden = (cb, once = false) => {
if (!listenersAdded) {
addListeners();
listenersAdded = true;
}
addEventListener('visibilitychange', ({ timeStamp }) => {
if (document.visibilityState === 'hidden') {
cb({ timeStamp, isUnloading });
}
}, { capture: true, once });
};

1
node_modules/web-vitals/dist/lib/whenInput.d.ts generated vendored Normal file
View file

@ -0,0 +1 @@
export declare const whenInput: () => Promise<Event>;

30
node_modules/web-vitals/dist/lib/whenInput.js generated vendored Normal file
View file

@ -0,0 +1,30 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
let inputPromise;
export const whenInput = () => {
if (!inputPromise) {
inputPromise = new Promise((r) => {
return ['scroll', 'keydown', 'pointerdown'].map((type) => {
addEventListener(type, r, {
once: true,
passive: true,
capture: true,
});
});
});
}
return inputPromise;
};

11
node_modules/web-vitals/dist/types.d.ts generated vendored Normal file
View file

@ -0,0 +1,11 @@
export interface Metric {
name: 'CLS' | 'FCP' | 'FID' | 'LCP' | 'TTFB';
value: number;
delta: number;
id: string;
isFinal: boolean;
entries: PerformanceEntry[];
}
export interface ReportHandler {
(metric: Metric): void;
}

15
node_modules/web-vitals/dist/types.js generated vendored Normal file
View file

@ -0,0 +1,15 @@
/*
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

1
node_modules/web-vitals/dist/web-vitals.es5.min.js generated vendored Normal file
View file

@ -0,0 +1 @@
var t,n,e=function(){return"".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)},i=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1;return{name:t,value:n,delta:0,entries:[],id:e(),isFinal:!1}},a=function(t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var e=new PerformanceObserver((function(t){return t.getEntries().map(n)}));return e.observe({type:t,buffered:!0}),e}}catch(t){}},r=!1,o=!1,s=function(t){r=!t.persisted},u=function(){addEventListener("pagehide",s),addEventListener("beforeunload",(function(){}))},c=function(t){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];o||(u(),o=!0),addEventListener("visibilitychange",(function(n){var e=n.timeStamp;"hidden"===document.visibilityState&&t({timeStamp:e,isUnloading:r})}),{capture:!0,once:n})},l=function(t,n,e,i){var a;return function(){e&&n.isFinal&&e.disconnect(),n.value>=0&&(i||n.isFinal||"hidden"===document.visibilityState)&&(n.delta=n.value-(a||0),(n.delta||n.isFinal||void 0===a)&&(t(n),a=n.value))}},p=function(t){var n,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=i("CLS",0),o=function(t){t.hadRecentInput||(r.value+=t.value,r.entries.push(t),n())},s=a("layout-shift",o);s&&(n=l(t,r,s,e),c((function(t){var e=t.isUnloading;s.takeRecords().map(o),e&&(r.isFinal=!0),n()})))},d=function(){return void 0===t&&(t="hidden"===document.visibilityState?0:1/0,c((function(n){var e=n.timeStamp;return t=e}),!0)),{get timeStamp(){return t}}},v=function(t){var n,e=i("FCP"),r=d(),o=a("paint",(function(t){"first-contentful-paint"===t.name&&t.startTime<r.timeStamp&&(e.value=t.startTime,e.isFinal=!0,e.entries.push(t),n())}));o&&(n=l(t,e,o))},f=function(t){var n=i("FID"),e=d(),r=function(t){t.startTime<e.timeStamp&&(n.value=t.processingStart-t.startTime,n.entries.push(t),n.isFinal=!0,s())},o=a("first-input",r),s=l(t,n,o);o?c((function(){o.takeRecords().map(r),o.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<e.timeStamp&&(n.value=t,n.isFinal=!0,n.entries=[{entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],s())}))},m=function(){return n||(n=new Promise((function(t){return["scroll","keydown","pointerdown"].map((function(n){addEventListener(n,t,{once:!0,passive:!0,capture:!0})}))}))),n},g=function(t){var n,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=i("LCP"),o=d(),s=function(t){var e=t.startTime;e<o.timeStamp?(r.value=e,r.entries.push(t)):r.isFinal=!0,n()},u=a("largest-contentful-paint",s);if(u){n=l(t,r,u,e);var p=function(){r.isFinal||(u.takeRecords().map(s),r.isFinal=!0,n())};m().then(p),c(p,!0)}},h=function(t){var n,e=i("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,n={entryType:"navigation",startTime:0};for(var e in t)"navigationStart"!==e&&"toJSON"!==e&&(n[e]=Math.max(t[e]-t.navigationStart,0));return n}();e.value=e.delta=n.responseStart,e.entries=[n],e.isFinal=!0,t(e)}catch(t){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)};export{p as getCLS,v as getFCP,f as getFID,g as getLCP,h as getTTFB};

View file

@ -0,0 +1 @@
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).webVitals={})}(this,(function(t){"use strict";var e,n,i=function(){return"".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)},a=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1;return{name:t,value:e,delta:0,entries:[],id:i(),isFinal:!1}},r=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},o=!1,s=!1,u=function(t){o=!t.persisted},c=function(){addEventListener("pagehide",u),addEventListener("beforeunload",(function(){}))},f=function(t){var e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];s||(c(),s=!0),addEventListener("visibilitychange",(function(e){var n=e.timeStamp;"hidden"===document.visibilityState&&t({timeStamp:n,isUnloading:o})}),{capture:!0,once:e})},d=function(t,e,n,i){var a;return function(){n&&e.isFinal&&n.disconnect(),e.value>=0&&(i||e.isFinal||"hidden"===document.visibilityState)&&(e.delta=e.value-(a||0),(e.delta||e.isFinal||void 0===a)&&(t(e),a=e.value))}},l=function(){return void 0===e&&(e="hidden"===document.visibilityState?0:1/0,f((function(t){var n=t.timeStamp;return e=n}),!0)),{get timeStamp(){return e}}},p=function(){return n||(n=new Promise((function(t){return["scroll","keydown","pointerdown"].map((function(e){addEventListener(e,t,{once:!0,passive:!0,capture:!0})}))}))),n};t.getCLS=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=a("CLS",0),o=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),e())},s=r("layout-shift",o);s&&(e=d(t,i,s,n),f((function(t){var n=t.isUnloading;s.takeRecords().map(o),n&&(i.isFinal=!0),e()})))},t.getFCP=function(t){var e,n=a("FCP"),i=l(),o=r("paint",(function(t){"first-contentful-paint"===t.name&&t.startTime<i.timeStamp&&(n.value=t.startTime,n.isFinal=!0,n.entries.push(t),e())}));o&&(e=d(t,n,o))},t.getFID=function(t){var e=a("FID"),n=l(),i=function(t){t.startTime<n.timeStamp&&(e.value=t.processingStart-t.startTime,e.entries.push(t),e.isFinal=!0,s())},o=r("first-input",i),s=d(t,e,o);o?f((function(){o.takeRecords().map(i),o.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<n.timeStamp&&(e.value=t,e.isFinal=!0,e.entries=[{entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],s())}))},t.getLCP=function(t){var e,n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=a("LCP"),o=l(),s=function(t){var n=t.startTime;n<o.timeStamp?(i.value=n,i.entries.push(t)):i.isFinal=!0,e()},u=r("largest-contentful-paint",s);if(u){e=d(t,i,u,n);var c=function(){i.isFinal||(u.takeRecords().map(s),i.isFinal=!0,e())};p().then(c),f(c,!0)}},t.getTTFB=function(t){var e,n=a("TTFB");e=function(){try{var e=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,e={entryType:"navigation",startTime:0};for(var n in t)"navigationStart"!==n&&"toJSON"!==n&&(e[n]=Math.max(t[n]-t.navigationStart,0));return e}();n.value=n.delta=e.responseStart,n.entries=[e],n.isFinal=!0,t(n)}catch(t){}},"complete"===document.readyState?setTimeout(e,0):addEventListener("pageshow",e)},Object.defineProperty(t,"__esModule",{value:!0})}));