mirror of
https://github.com/whyour/qinglong.git
synced 2026-10-18 18:33:06 +08:00
fix: report page load timing after load handlers complete
This commit is contained in:
+12
-23
@@ -18,6 +18,7 @@ import defaultProps from './defaultProps';
|
||||
import './index.less';
|
||||
import { init } from '../utils/init';
|
||||
import WebSocketManager from '../utils/websocket';
|
||||
import { observePageLoadTiming } from '../utils/navigationTiming';
|
||||
|
||||
export interface SharedContext {
|
||||
headerStyle: React.CSSProperties;
|
||||
@@ -220,29 +221,17 @@ export default function () {
|
||||
}, [user]);
|
||||
|
||||
useEffect(() => {
|
||||
window.onload = () => {
|
||||
const timing = performance.timing;
|
||||
console.log(
|
||||
intl.get('白屏时间', {
|
||||
duration: timing.responseStart - timing.navigationStart,
|
||||
}),
|
||||
);
|
||||
console.log(
|
||||
intl.get('请求完毕至DOM加载', {
|
||||
duration: timing.domInteractive - timing.responseEnd,
|
||||
}),
|
||||
);
|
||||
console.log(
|
||||
intl.get('解释DOM树耗时', {
|
||||
duration: timing.domComplete - timing.domInteractive,
|
||||
}),
|
||||
);
|
||||
console.log(
|
||||
intl.get('从开始至load总耗时', {
|
||||
duration: timing.loadEventEnd - timing.navigationStart,
|
||||
}),
|
||||
);
|
||||
};
|
||||
return observePageLoadTiming((durations) => {
|
||||
const metrics = [
|
||||
['白屏时间', durations.responseTime],
|
||||
['请求完毕至DOM加载', durations.domReadyTime],
|
||||
['解释DOM树耗时', durations.domParseTime],
|
||||
['从开始至load总耗时', durations.loadTime],
|
||||
] as const;
|
||||
for (const [label, duration] of metrics) {
|
||||
if (duration !== undefined) console.log(intl.get(label, { duration }));
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (initLoading) {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
export interface PageLoadDurations {
|
||||
responseTime?: number;
|
||||
domReadyTime?: number;
|
||||
domParseTime?: number;
|
||||
loadTime?: number;
|
||||
}
|
||||
|
||||
export function observePageLoadTiming(
|
||||
report: (durations: PageLoadDurations) => void,
|
||||
): () => void {
|
||||
let timer: number | undefined;
|
||||
let disposed = false;
|
||||
|
||||
const schedule = () => {
|
||||
// loadEventEnd is still zero inside the load handler. Read it on the next
|
||||
// task, after every load listener has returned, including on late mounts.
|
||||
timer = window.setTimeout(() => {
|
||||
if (disposed) return;
|
||||
const navigation = window.performance.getEntriesByType?.(
|
||||
'navigation',
|
||||
)[0] as PerformanceNavigationTiming | undefined;
|
||||
const timing = navigation || window.performance.timing;
|
||||
if (!timing) return;
|
||||
const start = navigation
|
||||
? navigation.startTime
|
||||
: window.performance.timing.navigationStart;
|
||||
if (!navigation && !(start > 0)) return;
|
||||
|
||||
const duration = (end: number, begin: number) =>
|
||||
Number.isFinite(end) &&
|
||||
Number.isFinite(begin) &&
|
||||
begin >= 0 &&
|
||||
end > 0 &&
|
||||
end >= begin
|
||||
? Math.round(end - begin)
|
||||
: undefined;
|
||||
|
||||
report({
|
||||
responseTime: duration(timing.responseStart, start),
|
||||
domReadyTime: duration(timing.domInteractive, timing.responseEnd),
|
||||
domParseTime: duration(timing.domComplete, timing.domInteractive),
|
||||
loadTime: duration(timing.loadEventEnd, start),
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
|
||||
if (document.readyState === 'complete') {
|
||||
schedule();
|
||||
} else {
|
||||
window.addEventListener('load', schedule, { once: true });
|
||||
}
|
||||
|
||||
return () => {
|
||||
disposed = true;
|
||||
window.removeEventListener('load', schedule);
|
||||
if (timer !== undefined) window.clearTimeout(timer);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user