Interaction to Next Paint (INP) measures how quickly a page responds to any user gesture — click, tap, or keyboard input. Google replaced FID with INP as a Core Web Vitals metric in March 2024 because INP captures the full session, not just the first interaction. INP above 200ms is classified as 'poor' and is driven almost entirely by long JavaScript tasks blocking the main thread. Marketing pages are high-risk: analytics, chat, heatmap, and ad pixel scripts are routinely copy-pasted from vendor docs as synchronous <script> tags in <head>, each forcing the browser to stop parsing HTML until the script downloads and executes. On mid-range Android, three synchronous third-party scripts can easily add 300–500ms of blocking time, breaching the INP threshold and degrading the Core Web Vitals page experience score.
High because synchronous third-party scripts cause measurable INP degradation on mid-range mobile devices, creating Core Web Vitals failures that feed into Google's Page Experience ranking signal.
Defer all non-critical JavaScript using the Next.js Script component — it enforces the right loading strategy and prevents accidental synchronous loading.
import Script from 'next/script'
// Analytics — wait until page is interactive
<Script
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXX"
strategy="afterInteractive"
/>
// Chat widget — defer until browser is idle
<Script
src="https://cdn.intercom.com/widget.js"
strategy="lazyOnload"
/>
For INP ≤ 200ms on mid-range mobile, keep total JavaScript on the critical rendering path under 150KB compressed. Run npx @next/bundle-analyzer to identify oversized chunks contributing to parse time.
ID: marketing-page-speed.core-web-vitals.fid-inp-threshold
Severity: high
What to look for: First Input Delay (FID, deprecated) and its replacement Interaction to Next Paint (INP) measure how quickly the page responds to user interaction. High FID/INP is caused by long JavaScript tasks blocking the main thread. Examine: (1) third-party scripts loaded synchronously in <head>, (2) large JavaScript bundles (>200KB) parsed on initial load, (3) heavy synchronous computations in event handlers, (4) missing scheduler.yield() or task chunking for long operations. Check for @next/bundle-analyzer or Lighthouse CI configuration. Count all instances found and enumerate each.
Pass criteria: No synchronous scripts block the main thread in <head>. Third-party scripts use async/defer or Next.js Script with afterInteractive/lazyOnload strategy. Main JS bundle is under 200KB. No heavy synchronous computations in event handlers on marketing pages.
Fail criteria: Multiple third-party scripts (analytics, chat, pixels) loaded synchronously without async/defer. Large JS bundles force long parse times. Event handlers contain heavy synchronous work.
Skip (N/A) when: Project has no interactive elements on marketing pages (purely static HTML with no JavaScript).
Detail on fail: "3 third-party scripts loaded synchronously in <head> — Intercom, GA, and Hotjar. Combined JS parse time likely exceeds 300ms on mid-range mobile, causing INP > 200ms."
Remediation: Defer all non-critical JavaScript:
// Next.js Script component — defer third-party scripts
import Script from 'next/script'
// Analytics — load after page is interactive
<Script src="https://www.googletagmanager.com/gtag/js" strategy="afterInteractive" />
// Chat widget — load when browser is idle
<Script src="https://cdn.intercom.com/widget.js" strategy="lazyOnload" />
For a 100ms INP budget on mid-range mobile, aim for total JavaScript < 150KB on the critical path.