Performance Monitoring

INP Monitoring: The Replacement for FID Explained

INP (Interaction to Next Paint) replaced FID as a Core Web Vital in 2024. Learn what INP measures, how to monitor it, and techniques to improve interaction latency.

AzMonitor TeamApril 5, 20257 min read · 1,019 wordsUpdated January 20, 2026
INPInteraction to Next PaintCore Web VitalsFID replacement

Interaction to Next Paint (INP) became a Core Web Vital in March 2024, replacing First Input Delay (FID). If you're still tracking FID, you're optimizing for a metric that no longer affects your Google search rankings. INP is both harder to optimize and more representative of real user experience — which is exactly why Google made the switch.

Why Google Replaced FID with INP

FID measured only the delay before the browser could begin processing the user's first interaction with a page. This was a useful but limited metric:

FID problems:

  • Only measured the first interaction (the most important one? Not always)
  • Didn't measure how long the interaction actually took to complete
  • Missed all subsequent interactions in a user session
  • Couldn't capture the rendering time after the handler ran

Consider a user who successfully clicks a button (good FID) but then spends the entire session struggling with laggy dropdowns, slow form inputs, and unresponsive filters. FID reported a great score; the user had a terrible experience.

INP measures the worst-case interaction throughout the entire session, giving a much more accurate picture of page responsiveness.

What INP Measures

INP = Time from user input to the next frame being painted that reflects the response to that input

User clicks/taps/keys → Input Processing → JavaScript handlers run → Layout → Paint

INP = Total time from input to paint
FID = Only the initial input delay (before handlers run)

INP captures the full cycle, including JavaScript handler execution time and the subsequent rendering work.

Interactions INP measures:

  • Mouse clicks
  • Touches on touchscreens
  • Keyboard key presses

Interactions INP ignores:

  • Hover events
  • Scroll events (these are handled separately via responsiveness metrics)
  • Pointer move events

How INP is calculated: INP takes all qualifying interactions during a session and reports the worst-case (highest) latency, with some outlier exclusion for very long sessions.

INP Thresholds

| Score | INP Value | User Experience | |-------|-----------|----------------| | Good | ≤ 200 milliseconds | Feels instant to users | | Needs Improvement | 200 – 500 milliseconds | Noticeable lag | | Poor | > 500 milliseconds | Clearly sluggish; frustrating |

The 200ms threshold is based on research showing users perceive interactions under 100ms as "instant" and interactions up to 200ms as "fast." Above 200ms, interactions start to feel sluggish.

Diagnosing High INP

High INP is almost always caused by long JavaScript tasks that block the main thread:

User interaction occurs
Main thread busy with long task (> 50ms)
Interaction event queued
Long task completes
Interaction handler runs
Rendering happens

Total time: Long task duration + handler time + render time = High INP

Tools for INP diagnosis:

  1. Chrome DevTools Performance tab: Record while interacting with your page. Look for "Long Task" indicators (red triangles).

  2. Web-vitals attribution API:

import { onINP } from 'web-vitals/attribution';

onINP(({ value, attribution }) => {
  const { eventTarget, eventType, loadState, inputDelay, processingDuration, presentationDelay } = attribution;
  
  console.log('Slow interaction:', {
    element: eventTarget,
    event: eventType,
    inputDelay,        // How long before handler started
    processingDuration, // How long handler ran
    presentationDelay,  // Time from handler end to paint
    total: value
  });
});
  1. Profiler extension: The Web Vitals Chrome extension shows real-time INP scores and highlights slow interactions.

Common Causes of High INP

Long JavaScript Event Handlers

The most direct cause: your click handler runs expensive computation synchronously:

// BAD: Expensive synchronous computation in click handler
button.addEventListener('click', () => {
  // This blocks the main thread for potentially hundreds of ms
  const result = processLargeDataset(data);
  updateUI(result);
});

// GOOD: Break up work, yield to browser between tasks
button.addEventListener('click', async () => {
  showLoadingState();
  
  // Yield to allow the browser to paint the loading state
  await scheduler.yield();
  
  // Run expensive work
  const result = await processInChunks(data);
  updateUI(result);
});

React/Framework Re-Render Cascades

In React applications, a single state change can trigger re-renders across a large component tree. If that re-render takes 200ms, every interaction that triggers it has poor INP.

// Optimization: Memoize expensive computations
const ExpensiveList = React.memo(({ items }) => {
  return items.map(item => <Item key={item.id} {...item} />);
});

// Optimization: Avoid re-rendering large lists on every state change
const [filter, setFilter] = useState('');
const filteredItems = useMemo(() => 
  items.filter(i => i.name.includes(filter)), 
  [items, filter]
);

Third-Party Script Interference

Third-party scripts (ads, analytics, chatbots) that run JavaScript on the main thread steal time from interaction handlers. A chatbot widget that runs every 500ms to check for messages directly worsens INP.

Audit third-party scripts in your DevTools Performance recording and evaluate whether their INP impact justifies their presence.

Layout Thrashing

Code that alternately reads and writes DOM layout properties forces the browser to recalculate layout repeatedly:

// BAD: Forces layout recalculation on every iteration
for (const element of elements) {
  element.style.width = element.offsetWidth + 10 + 'px';  // Read then write
}

// GOOD: Batch reads, then batch writes
const widths = elements.map(el => el.offsetWidth);  // All reads
elements.forEach((el, i) => el.style.width = widths[i] + 10 + 'px');  // All writes

Monitoring INP Continuously

INP is a field metric — it requires real user interactions to measure. Lab tools can simulate interactions but don't capture the full diversity of user behavior.

Field monitoring strategy:

  1. Implement the web-vitals library and capture INP from real users
  2. Segment by page, device type, and interaction type
  3. Alert when P75 INP exceeds 200ms for a significant page or user segment
  4. Track INP trends over time to catch regressions
// Send INP data with page context
onINP(({ value, attribution }) => {
  sendMetric({
    metric: 'inp',
    value,
    page: window.location.pathname,
    interactionTarget: attribution.eventTarget,
    interactionType: attribution.eventType,
    device: getDeviceType(),
  });
});

Lab monitoring for regression detection:

Even though INP is a field metric, lab tools can detect INP regressions if you script specific interactions. AzMonitor's Playwright-based performance checks can click specific buttons and measure interaction responsiveness.

Add performance monitoring to AzMonitor alongside availability monitoring for complete web performance coverage. See also Core Web Vitals monitoring for the full picture.

Tags:INPInteraction to Next PaintCore Web VitalsFID replacement
Back to blog
A
AzMonitor Team
The AzMonitor team writes guides based on experience monitoring millions of endpoints daily across 10,000+ customer environments. Our expertise covers uptime monitoring, SRE practices, and reliability engineering.
Try AzMonitor free

3 monitors free forever · No credit card needed · Set up in 2 minutes

Start monitoring free →