Skip to content

Instantly share code, notes, and snippets.

@otakustay
Created November 7, 2019 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save otakustay/6cb8bf6eafa37c260288ee2459dfbaa6 to your computer and use it in GitHub Desktop.
Save otakustay/6cb8bf6eafa37c260288ee2459dfbaa6 to your computer and use it in GitHub Desktop.
usePerformanceTiming
import {useRef, useLayoutEffect} from 'react';
interface PerformanceTiming {
firstRender: number;
firstLayout: number;
firstMeaningfulRender: number;
firstMeaningfulLayout: number;
}
const usePerformanceRecord = () => {
const time = useRef(0);
return {
time: time.current,
record() {
if (!time.current) {
time.current = performance.now();
}
},
};
};
const usePerformanceTiming = (isCurrentlyMeaningful: boolean, callback: (timing: PerformanceTiming) => void) => {
const firstRender = usePerformanceRecord();
const firstLayout = usePerformanceRecord();
const firstMeaningfulRender = usePerformanceRecord();
const hasMeaningfulLayout = useRef(false);
firstRender.record();
isCurrentlyMeaningful && firstMeaningfulRender.record();
useLayoutEffect(
() => {
firstLayout.record();
if (!hasMeaningfulLayout) {
hasMeaningfulLayout.current = true;
const timing = {
firstRender: firstRender.time,
firstLayout: firstLayout.time,
firstMeaningfulRender: firstMeaningfulRender.time,
firstMeaningfulLayout: performance.now(),
};
callback(timing);
}
},
[isCurrentlyMeaningful]
);
};
const Foo = () => {
const {loading, data} = useFetch(api);
usePerformanceTiming(!!data, timing => console.log(timing));
return (
<div>
{data}
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment