useINP
Description and use case
useINP tracks the worst Interaction to Next Paint observed during the current page view. It uses PerformanceObserver with the event entry type, so it does not require the web-vitals package.
API signature
function useINP(options?: UseINPOptions): UseINPReturn;
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
options.onMetric | (metric: INPMetric) => void | No | Callback fired whenever the worst interaction changes. |
options.durationThreshold | number | No | Minimum Event Timing duration observed by the browser. Defaults to 40. |
options.enabled | boolean | No | Set false to disable the observer. |
Return value
| Field | Type | Description |
|---|---|---|
metric | INPMetric | null | Worst interaction metric seen so far. |
value | number | null | INP latency in milliseconds. |
rating | INPRating | null | good, needs-improvement, or poor. |
isSupported | boolean | Whether this browser supports Event Timing entries. |
Live interactive demo (StackBlitz)
GitHub Pages does not serve the isolation headers required for embedded StackBlitz WebContainers. Open the demo in StackBlitz to run it interactively.
Code example
import { useINP } from 'react-perf-hooks';
export function INPOverlay() {
const { value, rating, isSupported } = useINP({
durationThreshold: 16,
onMetric: (metric) => {
navigator.sendBeacon('/api/inp', JSON.stringify(metric));
},
});
if (!isSupported) {
return <p>INP is not available in this browser.</p>;
}
return <p>INP: {value === null ? 'waiting' : `${value.toFixed(0)} ms (${rating})`}</p>;
}