>_
EngineeringNotes
Back to Next.js Mastery

Rendering & Components

Next.js redefines the boundaries between server and client. By moving the heavy lifting to the server, we achieve unprecedented performance.

1. Big Picture

In modern Next.js (App Router), components are divided into two distinct categories:

Server Components

The default and high-performance standard for building modern apps.

Client Components

Components marked with "use client" for interactivity.

Why This Concept Exists

Traditional React (CSR) requires the browser to download massive JS bundles before anything renders. Next.js moves as much work as possible to the server to reduce bundle sizes and speed up initial loads.

2. Server Components

Server Components run only on the server and send static HTML to the client.

Key Characteristics

  • No JavaScript sent to client (0kb bundle size)
  • Direct Database / API access
  • Optimized for SEO and instant rendering

Limitations

  • • No useState or useEffect hooks
  • • No event handlers (onClick, focus)
  • • No access to browser APIs (window, localStorage)
page.js (Server Component)
javascript
// Server Component by default
export default async function Page() {
  const data = await fetch("https://api.example.com/data");
  const json = await data.json();

  return <div>{json.title}</div>;
}

Execution Flow

1. Server executes component
2. HTML generated (No JS)
3. Browser renders instantly

3. Client Components

Defined with the "use client" directive to enable browser-side interactivity.

Core Features

  • Full access to React Hooks (State, Effects)
  • Browser Event Handling (onClick, OnScroll)
  • Access to Browser APIs (localStorage, DOM)

Lifecycle

Server sends HTML + JS. Browser executes JS to make UI interactive (Hydration).

counter.js (Client Component)
javascript
"use client";

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(count + 1)}>
       Progress: {count}
    </button>
  );
}

Server vs Client Comparison

FeatureServer ComponentClient Component
Runs onServerBrowser
JS sent to clientNoYes
InteractivityNoYes
Data fetchingDirect (async)via API / Hooks
PerformanceHigh InitialHigh Interactive
Bundle sizeZero / SmallLarger (React logic)

6. Hydration

Definition

Hydration is the process where React attaches event listeners to server-rendered HTML, making the UI interactive in the browser.

Step 011. HTML Sent
Step 022. Browser UI Layout
Step 033. JS Loads
Step 044. Hydration (Interactive)

Hydration Mismatch

Occurs when the server-rendered HTML does not match the initial client-side render result.

The Common Culprit: Time

Calculating new Date().toLocaleTimeString() on the server vs client leads to different values, triggering a React warning.

hydration-fix.js
javascript
"use client";

// Fix: Ensure client-only state happens after mount
useEffect(() => {
  setTime(new Date());
}, []);

Advanced Rendering Strategies

1. SSR (Server-Side)

Runs on every request. Ideal for high-dynamic content requiring fresh data on every page load.

2. SSG (Static Site)

Generated at build time. Extreme speed and zero infrastructure load at runtime.

3. ISR (Incremental)

Updates static pages in the background after deployment without a full site rebuild.

4. Streaming

Sends UI in chunks. Users see the Header and Layout while slow-fetching content is loading.

Performance Insights (Interview Gold)

Why Server Components are Powerful

  • Reduced JS Bundle: Moves libraries and logic to the server.
  • Better SEO: Full page content is available to crawlers instantly.
  • Direct DB Calls: Zero latency added for internal network requests.

When to use Client Components

  • For Interactive State (useState)
  • For Side Effects (useEffect)
  • For Browser APIs (window)

// Composition Rule:
Server Comp can include Client Comp
Client Comp CANNOT include Server logic.

Advanced Interview Questions