I am trying to to use the PerformanceNavigationTiming
API to generate a page load metric.
The MDN API document linked above says that the PerformanceEntry.duration
should give me what I need because it:
[r]eturns a timestamp that is the difference between the PerformanceNavigationTiming.loadEventEnd and PerformanceEntry.startTime properties.
However, when I check this property, I get simply 0
. I’m accessing this API from within a React hook that runs a useEffect
function that wait for the window
load event and then checks the api like so:
export const useReportPageLoadTime = () => { useEffect(() => { const reportTime = () => { let navPerformance: PerformanceEntry navPerformance = window.performance.getEntriesByType('navigation')[0] console.log({ duration: navPerformance.duration, blob: navPerformance.toJSON() }) } if (document.readyState === 'complete') { reportTime() return null } else { window.addEventListener('load', reportTime) return () => window.removeEventListener('load', reportTime) } }, []) }
As you can see there, I also call toJSON
on the performance entry and indeed it shows that the values upon which duration
(startTime
and loadEventEnd
) are both 0
as well:
Does anyone know why I am getting this value?
Advertisement
Answer
I was finally able to get this to work using a different method than the event listener. It certainly is logical that the data should be ready when the load
event fires, but the only way I was able to get the data was to use another feature of the Performance API: the PerformanceObserver
, which fires a callback when a new piece of data has become available.
Here is the code that worked for me:
export const useReportPageLoadMetrics = () => { useEffect(() => { const perfObserver = new PerformanceObserver((observedEntries) => { const entry: PerformanceEntry = observedEntries.getEntriesByType('navigation')[0] console.log('pageload time: ', entry.duration) }) perfObserver.observe({ type: 'navigation', buffered: true }) }, []) }