# Long tasks blocking the main thread in Next.js

> How to fix long tasks blocking the main thread in Next.js — with the exact fix and copy-paste code.

_Category: Performance · Detector `long-task-attribution` · Severity: warning_

The browser runs your JavaScript on the same single thread it uses to respond to clicks and paint frames, so any task that runs too long freezes everything — the page can’t respond to input while it works. This is what wrecks INP (Interaction to Next Paint) and makes a page feel janky right after load. AI code tends to do expensive work synchronously in render or on mount instead of chunking or deferring it.

## The fix for Next.js

Move work off the client entirely: do the heavy computation in a Server Component or Server Action, and `next/dynamic`-import client-only heavy widgets so they don’t block first interaction.

```tsx
import dynamic from 'next/dynamic'
const Chart = dynamic(() => import('./Chart'), { ssr: false, loading: () => <Skeleton /> })
```

### Steps

1. Profile to find the script behind the long task (VibeCheck names it)
2. Move heavy pure computation into a Web Worker, or chunk it with yielding
3. Defer non-critical work with `requestIdleCallback` / `scheduler.yield`

## How VibeCheck detects it

The `long-task-attribution` detector flags this live in the browser and reports it to the widget's Problems list — and to your coding agent over MCP.

- **Issue string:** `Script causing long frames: bundle.js`
- **Threshold:** A single script attributed to more than 3 long animation frames (LoAF)

## FAQ

### What counts as a long task?

The browser flags any task that occupies the main thread for 50ms or more. VibeCheck goes further and attributes long animation frames back to the specific script responsible, so you know what to fix.

### When should I use a Web Worker vs chunking?

Use a Worker for pure, CPU-bound computation with no DOM access (parsing, crunching, transforming data). Use chunking/yielding when the work must touch the DOM or React state and can be spread across frames.

### How does this relate to INP?

INP measures how long the page takes to visually respond to an interaction. Long tasks are the main cause of poor INP — while a long task runs, the browser can’t process the click or paint the response.

See the general, framework-agnostic fix: https://vibecheck.wcgw.fun/fix/long-tasks.md

---

Fix guide from VibeCheck — https://vibecheck.wcgw.fun/fix/long-tasks. Full site index for LLMs: https://vibecheck.wcgw.fun/llms.txt
