Interaction to Next Paint (INP) replaced First Input Delay as a Core Web Vital in March 2024 — poor INP (over 200ms) is now a ranking penalty in the Page Experience signal. INP measures the worst interaction delay across a user session, making synchronous JavaScript in event handlers the primary culprit: a button click that triggers a heavy filter operation blocks the main thread, the browser cannot paint the response for hundreds of milliseconds, and Google records a poor INP event. iso-25010:2011 performance-efficiency captures this: sites shipping large monolithic bundles without code splitting routinely fail INP thresholds because every interaction competes with the cost of parsing and executing the full bundle.
Medium because poor INP affects Page Experience ranking on mobile and creates frustrating interaction delays, but the impact is session-wide rather than page-load immediate, making it less urgent than LCP or CLS failures.
Use dynamic imports for components not needed on initial render. Wrap state updates that trigger heavy re-renders in startTransition to prevent them from blocking user input.
// app/products/page.tsx — defer heavy filter component
import { lazy, Suspense } from 'react'
const FilterPanel = lazy(() => import('@/components/filter-panel'))
// components/search.tsx — non-blocking state update
import { useCallback, useTransition } from 'react'
const [isPending, startTransition] = useTransition()
const handleSearch = useCallback((query: string) => {
startTransition(() => {
setFilteredResults(heavyFilter(allResults, query))
})
}, [allResults])
For third-party scripts (analytics, chat, A/B testing tools), replace inline <script> tags in <head> with the Next.js <Script> component using strategy="afterInteractive" in app/layout.tsx. Import specific functions from large libraries instead of the full package — e.g., import { debounce } from 'lodash-es' instead of import _ from 'lodash'. See the Performance & Load Readiness audit for INP measurement methodology.
ID: marketing-advanced-seo.mobile-performance-seo.interaction-responsiveness
Severity: medium
What to look for: Count all interactive elements (buttons, form inputs, links with click handlers). Enumerate which have heavy JavaScript execution on interaction that could cause delays over 200ms. Interaction to Next Paint (INP), which replaced First Input Delay (FID) as a Core Web Vital in 2024, measures how quickly your page responds to user interactions. Check for patterns indicating poor interaction responsiveness: (1) large JavaScript bundles with no code splitting — no dynamic imports, no React.lazy, all components imported statically in a medium or large project, (2) heavy synchronous operations in event handlers, (3) third-party scripts loaded synchronously without defer or async attributes (or without the Next.js Script component with a deferred strategy), (4) entire large libraries imported when only a subset is used.
Pass criteria: The project uses code splitting (dynamic imports or framework-level route-based splitting). Third-party scripts are loaded asynchronously. No obvious synchronous blocking operations in event handlers. No more than 5% of interactive elements should trigger JavaScript execution over 200ms (INP threshold).
Fail criteria: No code splitting patterns detected in a medium or large project. Third-party analytics/marketing scripts are loaded synchronously in <head>. Heavy libraries imported in full when only a small portion is needed.
Skip (N/A) when: The project is a static site with minimal JavaScript. Or project is API-only.
Cross-reference: For LCP that also affects perceived responsiveness, see lcp-optimization.
Detail on fail: "INP risk: no code splitting detected in a medium-sized project — all routes appear to share a single JavaScript bundle. 2 third-party scripts loaded synchronously in <head>. Heavy form validation library imported in full."
Remediation: Keep the main thread free during interactions. Use dynamic imports for heavy components that are not needed on initial render. Load third-party scripts using the Next.js Script component with strategy="afterInteractive" or strategy="lazyOnload". Import specific functions from large libraries rather than the entire library. For a complete performance analysis including INP measurement, the Performance & Load Readiness audit provides detailed guidance.
// components/search.tsx — defer heavy processing
const handleSearch = useCallback(() => {
startTransition(() => { setResults(heavyFilter(data)) }) // non-blocking
}, [data])