65 lines
2.4 KiB
JavaScript
65 lines
2.4 KiB
JavaScript
|
/*
|
||
|
* 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 {
|
||
|
// Queue a task so the callback runs after `loadEventEnd`.
|
||
|
addEventListener('load', () => setTimeout(callback, 0));
|
||
|
}
|
||
|
};
|
||
|
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;
|
||
|
// In some cases the value reported is negative or is larger
|
||
|
// than the current page time. Ignore these cases:
|
||
|
// https://github.com/GoogleChrome/web-vitals/issues/137
|
||
|
// https://github.com/GoogleChrome/web-vitals/issues/162
|
||
|
if (metric.value < 0 || metric.value > performance.now())
|
||
|
return;
|
||
|
metric.entries = [navigationEntry];
|
||
|
onReport(metric);
|
||
|
}
|
||
|
catch (error) {
|
||
|
// Do nothing.
|
||
|
}
|
||
|
});
|
||
|
};
|