Update app and tooling
This commit is contained in:
parent
3046531bdd
commit
e620ec7349
4950 changed files with 2975120 additions and 10 deletions
57
node_modules/web-vitals/src/getCLS.ts
generated
vendored
Normal file
57
node_modules/web-vitals/src/getCLS.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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, PerformanceEntryHandler} from './lib/observe.js';
|
||||
import {onHidden} from './lib/onHidden.js';
|
||||
import {bindReporter} from './lib/bindReporter.js';
|
||||
import {ReportHandler} from './types.js';
|
||||
|
||||
|
||||
// https://wicg.github.io/layout-instability/#sec-layout-shift
|
||||
interface LayoutShift extends PerformanceEntry {
|
||||
value: number;
|
||||
hadRecentInput: boolean;
|
||||
}
|
||||
|
||||
export const getCLS = (onReport: ReportHandler, reportAllChanges = false) => {
|
||||
const metric = initMetric('CLS', 0);
|
||||
|
||||
let report: ReturnType<typeof bindReporter>;
|
||||
|
||||
const entryHandler = (entry: LayoutShift) => {
|
||||
// Only count layout shifts without recent user input.
|
||||
if (!entry.hadRecentInput) {
|
||||
(metric.value as number) += entry.value;
|
||||
metric.entries.push(entry);
|
||||
report();
|
||||
}
|
||||
};
|
||||
|
||||
const po = observe('layout-shift', entryHandler as PerformanceEntryHandler);
|
||||
if (po) {
|
||||
report = bindReporter(onReport, metric, po, reportAllChanges);
|
||||
|
||||
onHidden(({isUnloading}) => {
|
||||
po.takeRecords().map(entryHandler as PerformanceEntryHandler);
|
||||
|
||||
if (isUnloading) {
|
||||
metric.isFinal = true;
|
||||
}
|
||||
report();
|
||||
});
|
||||
}
|
||||
};
|
||||
46
node_modules/web-vitals/src/getFCP.ts
generated
vendored
Normal file
46
node_modules/web-vitals/src/getFCP.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 {ReportHandler} from './types.js';
|
||||
|
||||
|
||||
export const getFCP = (onReport: ReportHandler) => {
|
||||
const metric = initMetric('FCP');
|
||||
const firstHidden = getFirstHidden();
|
||||
|
||||
let report: ReturnType<typeof bindReporter>;
|
||||
|
||||
const entryHandler = (entry: PerformanceEntry) => {
|
||||
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);
|
||||
}
|
||||
};
|
||||
88
node_modules/web-vitals/src/getFID.ts
generated
vendored
Normal file
88
node_modules/web-vitals/src/getFID.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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, PerformanceEntryHandler} from './lib/observe.js';
|
||||
import {onHidden} from './lib/onHidden.js';
|
||||
import {ReportHandler} from './types.js';
|
||||
|
||||
|
||||
interface FIDPolyfillCallback {
|
||||
(value: number, event: Event): void;
|
||||
}
|
||||
|
||||
interface FIDPolyfill {
|
||||
onFirstInputDelay: (onReport: FIDPolyfillCallback) => void;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
perfMetrics: FIDPolyfill;
|
||||
}
|
||||
}
|
||||
|
||||
// https://wicg.github.io/event-timing/#sec-performance-event-timing
|
||||
interface PerformanceEventTiming extends PerformanceEntry {
|
||||
processingStart: DOMHighResTimeStamp;
|
||||
cancelable?: boolean;
|
||||
target?: Element;
|
||||
}
|
||||
|
||||
export const getFID = (onReport: ReportHandler) => {
|
||||
const metric = initMetric('FID');
|
||||
const firstHidden = getFirstHidden();
|
||||
|
||||
const entryHandler = (entry: PerformanceEventTiming) => {
|
||||
// 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 as PerformanceEntryHandler);
|
||||
const report = bindReporter(onReport, metric, po);
|
||||
|
||||
if (po) {
|
||||
onHidden(() => {
|
||||
po.takeRecords().map(entryHandler as PerformanceEntryHandler);
|
||||
po.disconnect();
|
||||
}, true);
|
||||
} else {
|
||||
if (window.perfMetrics && window.perfMetrics.onFirstInputDelay) {
|
||||
window.perfMetrics.onFirstInputDelay((value: number, event: 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,
|
||||
} as PerformanceEventTiming];
|
||||
report();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
65
node_modules/web-vitals/src/getLCP.ts
generated
vendored
Normal file
65
node_modules/web-vitals/src/getLCP.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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, PerformanceEntryHandler} from './lib/observe.js';
|
||||
import {onHidden} from './lib/onHidden.js';
|
||||
import {whenInput} from './lib/whenInput.js';
|
||||
import {ReportHandler} from './types.js';
|
||||
|
||||
|
||||
export const getLCP = (onReport: ReportHandler, reportAllChanges = false) => {
|
||||
const metric = initMetric('LCP');
|
||||
const firstHidden = getFirstHidden();
|
||||
|
||||
let report: ReturnType<typeof bindReporter>;
|
||||
|
||||
const entryHandler = (entry: PerformanceEntry) => {
|
||||
// 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 as PerformanceEntryHandler);
|
||||
metric.isFinal = true;
|
||||
report();
|
||||
}
|
||||
}
|
||||
|
||||
whenInput().then(onFinal);
|
||||
onHidden(onFinal, true);
|
||||
}
|
||||
};
|
||||
117
node_modules/web-vitals/src/getTTFB.ts
generated
vendored
Normal file
117
node_modules/web-vitals/src/getTTFB.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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 {ReportHandler} from './types.js';
|
||||
|
||||
|
||||
interface NavigationEntryShim {
|
||||
// From `PerformanceNavigationTimingEntry`.
|
||||
entryType: string;
|
||||
startTime: number;
|
||||
|
||||
// From `performance.timing`.
|
||||
connectEnd?: number;
|
||||
connectStart?: number;
|
||||
domComplete?: number;
|
||||
domContentLoadedEventEnd?: number;
|
||||
domContentLoadedEventStart?: number;
|
||||
domInteractive?: number;
|
||||
domainLookupEnd?: number;
|
||||
domainLookupStart?: number;
|
||||
fetchStart?: number;
|
||||
loadEventEnd?: number;
|
||||
loadEventStart?: number;
|
||||
redirectEnd?: number;
|
||||
redirectStart?: number;
|
||||
requestStart?: number;
|
||||
responseEnd?: number;
|
||||
responseStart?: number;
|
||||
secureConnectionStart?: number;
|
||||
unloadEventEnd?: number;
|
||||
unloadEventStart?: number;
|
||||
}
|
||||
|
||||
type PerformanceTimingKeys =
|
||||
'connectEnd' |
|
||||
'connectStart' |
|
||||
'domComplete' |
|
||||
'domContentLoadedEventEnd' |
|
||||
'domContentLoadedEventStart' |
|
||||
'domInteractive' |
|
||||
'domainLookupEnd' |
|
||||
'domainLookupStart' |
|
||||
'fetchStart' |
|
||||
'loadEventEnd' |
|
||||
'loadEventStart' |
|
||||
'redirectEnd' |
|
||||
'redirectStart' |
|
||||
'requestStart' |
|
||||
'responseEnd' |
|
||||
'responseStart' |
|
||||
'secureConnectionStart' |
|
||||
'unloadEventEnd' |
|
||||
'unloadEventStart';
|
||||
|
||||
const afterLoad = (callback: () => void) => {
|
||||
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: NavigationEntryShim = {
|
||||
entryType: 'navigation',
|
||||
startTime: 0,
|
||||
};
|
||||
|
||||
for (const key in timing) {
|
||||
if (key !== 'navigationStart' && key !== 'toJSON') {
|
||||
navigationEntry[key as PerformanceTimingKeys] = Math.max(
|
||||
timing[key as PerformanceTimingKeys] - timing.navigationStart, 0);
|
||||
}
|
||||
}
|
||||
return navigationEntry as PerformanceNavigationTiming;
|
||||
};
|
||||
|
||||
export const getTTFB = (onReport: ReportHandler) => {
|
||||
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 as PerformanceNavigationTiming).responseStart;
|
||||
|
||||
metric.entries = [navigationEntry];
|
||||
metric.isFinal = true;
|
||||
|
||||
onReport(metric);
|
||||
} catch (error) {
|
||||
// Do nothing.
|
||||
}
|
||||
});
|
||||
};
|
||||
23
node_modules/web-vitals/src/index.ts
generated
vendored
Normal file
23
node_modules/web-vitals/src/index.ts
generated
vendored
Normal 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.
|
||||
*/
|
||||
|
||||
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';
|
||||
48
node_modules/web-vitals/src/lib/bindReporter.ts
generated
vendored
Normal file
48
node_modules/web-vitals/src/lib/bindReporter.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 {Metric, ReportHandler} from '../types.js';
|
||||
|
||||
|
||||
export const bindReporter = (
|
||||
callback: ReportHandler,
|
||||
metric: Metric,
|
||||
po: PerformanceObserver | undefined,
|
||||
observeAllUpdates?: boolean,
|
||||
) => {
|
||||
let prevValue: number;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
node_modules/web-vitals/src/lib/generateUniqueID.ts
generated
vendored
Normal file
24
node_modules/web-vitals/src/lib/generateUniqueID.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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}`;
|
||||
};
|
||||
39
node_modules/web-vitals/src/lib/getFirstHidden.ts
generated
vendored
Normal file
39
node_modules/web-vitals/src/lib/getFirstHidden.ts
generated
vendored
Normal 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 {onHidden} from './onHidden.js';
|
||||
|
||||
|
||||
let firstHiddenTime: number
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
30
node_modules/web-vitals/src/lib/initMetric.ts
generated
vendored
Normal file
30
node_modules/web-vitals/src/lib/initMetric.ts
generated
vendored
Normal 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.
|
||||
*/
|
||||
|
||||
import {Metric} from '../types.js';
|
||||
import {generateUniqueID} from './generateUniqueID.js';
|
||||
|
||||
|
||||
export const initMetric = (name: Metric['name'], value = -1): Metric => {
|
||||
return {
|
||||
name,
|
||||
value,
|
||||
delta: 0,
|
||||
entries: [],
|
||||
id: generateUniqueID(),
|
||||
isFinal: false
|
||||
};
|
||||
};
|
||||
45
node_modules/web-vitals/src/lib/observe.ts
generated
vendored
Normal file
45
node_modules/web-vitals/src/lib/observe.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 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 const observe = (
|
||||
type: string,
|
||||
callback: PerformanceEntryHandler,
|
||||
): PerformanceObserver | undefined => {
|
||||
try {
|
||||
if (PerformanceObserver.supportedEntryTypes.includes(type)) {
|
||||
const po: PerformanceObserver =
|
||||
new PerformanceObserver((l) => l.getEntries().map(callback));
|
||||
|
||||
po.observe({type, buffered: true});
|
||||
return po;
|
||||
}
|
||||
} catch (e) {
|
||||
// Do nothing.
|
||||
}
|
||||
return;
|
||||
};
|
||||
50
node_modules/web-vitals/src/lib/onHidden.ts
generated
vendored
Normal file
50
node_modules/web-vitals/src/lib/onHidden.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 interface OnHiddenCallback {
|
||||
// TODO(philipwalton): add `isPersisted` if needed for bfcache.
|
||||
({timeStamp, isUnloading}: {timeStamp: number; isUnloading: boolean}): void;
|
||||
}
|
||||
|
||||
let isUnloading = false;
|
||||
let listenersAdded = false;
|
||||
|
||||
const onPageHide = (event: PageTransitionEvent) => {
|
||||
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: OnHiddenCallback, once = false) => {
|
||||
if (!listenersAdded) {
|
||||
addListeners();
|
||||
listenersAdded = true;
|
||||
}
|
||||
|
||||
addEventListener('visibilitychange', ({timeStamp}) => {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
cb({timeStamp, isUnloading});
|
||||
}
|
||||
}, {capture: true, once});
|
||||
};
|
||||
32
node_modules/web-vitals/src/lib/whenInput.ts
generated
vendored
Normal file
32
node_modules/web-vitals/src/lib/whenInput.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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: Promise<Event>;
|
||||
|
||||
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;
|
||||
};
|
||||
45
node_modules/web-vitals/src/types.ts
generated
vendored
Normal file
45
node_modules/web-vitals/src/types.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 interface Metric {
|
||||
// The name of the metric (in acronym form).
|
||||
name: 'CLS' | 'FCP' | 'FID' | 'LCP' | 'TTFB';
|
||||
|
||||
// The current value of the metric.
|
||||
value: number;
|
||||
|
||||
// The delta between the current value and the last-reported value.
|
||||
// On the first report, `delta` and `value` will always be the same.
|
||||
delta: number;
|
||||
|
||||
// A unique ID representing this particular metric that's specific to the
|
||||
// current page. This ID can be used by an analytics tool to dedupe
|
||||
// multiple values sent for the same metric, or to group multiple deltas
|
||||
// together and calculate a total.
|
||||
id: string;
|
||||
|
||||
// `false` if the value of the metric may change in the future,
|
||||
// for the current page.
|
||||
isFinal: boolean;
|
||||
|
||||
// Any performance entries used in the metric value calculation.
|
||||
// Note, entries will be added to the array as the value changes.
|
||||
entries: PerformanceEntry[];
|
||||
}
|
||||
|
||||
export interface ReportHandler {
|
||||
(metric: Metric): void;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue