Performance: Why client components handle interactivity
This affects how fast the page becomes interactive and how smoothly user inputs are handled.
'use client'; export default function InteractiveButton() { return <button onClick={() => alert('Clicked!')}>Click me</button>; }
export default function Page() { return <button onClick={() => alert('Clicked!')}>Click me</button>; } // Entire component is server component by default
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Server component with interactivity | Minimal DOM nodes | 0 reflows for events | No paint cost for events | [X] Bad - no client event handling |
| Client component with interactivity | Minimal DOM nodes | 0 reflows for events | Paint cost only on interaction | [OK] Good - responsive interactivity |
'use client' at the top of the component file uses the exact correct syntax: 'use client' at the top."use client";
import { useState } from 'react';
export default function ClickCounter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>Clicked {count} times</button>
);
}"use client";
import { useState } from 'react';
export default function Toggle() {
const [on, setOn] = useState(false);
return (
<button onClick={setOn(!on)}>{on ? 'ON' : 'OFF'}</button>
);
}"use client";
import { useState } from 'react';
export default function DarkModeToggle() {
const [dark, setDark] = useState(false);
return (
<button onClick={() => {
setDark(!dark);
document.body.classList.toggle('dark-theme', !dark);
}}>
{dark ? 'Light Mode' : 'Dark Mode'}
</button>
);
}Pass the test and this pattern moves unknown