01Server Components vs Client Components

ใน App Router หน้าและ layout เป็น Server Components โดยค่าเริ่มต้น เหมาะกับ data fetching ใกล้แหล่งข้อมูล, ใช้ secret ฝั่ง server และลด client bundle ส่วน Client Component ใช้เมื่อจำเป็นต้องมี state, event handler, effect, custom hook หรือ browser API

"use client" สร้าง client boundary และ module ที่ import ลงมาจะอยู่ฝั่ง client ด้วย จึงควรวาง boundary ให้ลึกเท่าที่ทำได้ เช่นให้หน้า policy เป็น Server Component แต่แยกปุ่มที่มี interaction เป็น Client Component เล็ก ๆ

app/policies/[id]/page.tsx
// app/policies/[id]/page.tsx — Server Component
import PolicyActions from './policy-actions'

export default async function PolicyPage({ params }: PageProps) {
  const { id } = await params
  const policy = await getPolicy(id)

  return (
    <main>
      <PolicySummary policy={policy} />
      <PolicyActions policyId={policy.id} />
    </main>
  )
}

// policy-actions.tsx
'use client'
export default function PolicyActions({ policyId }: Props) {
  // state, event handlers และ browser APIs อยู่ที่นี่
}

02เลือก Rendering Strategy จากความสดของข้อมูล

Static / SSG

หน้าที่เหมือนกันทุกคนและเปลี่ยนน้อย เร็วและ cache ง่าย แต่ข้อมูลอาจเก่า

ISR / Cached

Catalog หรือ content ที่ยอม stale ชั่วคราว ลด server load แต่ต้องออกแบบ invalidation

Dynamic / SSR

ข้อมูลตาม user/request หรือจำเป็นต้องสด ถูกต้องล่าสุดแต่ใช้ server ต่อ request

CSR

Interaction หลังโหลดหรือข้อมูลเฉพาะ browser ยืดหยุ่นแต่เพิ่ม JS และ waterfall ได้

คำตอบระดับ Senior ควรบอกว่า strategy เป็น รายส่วนของหน้า ไม่จำเป็นต้องเลือกหนึ่งแบบทั้ง route เสมอ และ caching semantics เปลี่ยนตามเวอร์ชัน จึงต้องตรวจเอกสารของเวอร์ชันที่ production ใช้อยู่

03Data fetching, Cache และ Waterfall

Waterfall เกิดเมื่อ request B รอ component A ทั้งที่เริ่มพร้อมกันได้ วิธีแก้คือเริ่ม promise เร็วแล้ว await ใกล้จุดใช้, ใช้ `Promise.all` กับข้อมูลอิสระ และวาง <Suspense> boundary เพื่อ stream ส่วนที่พร้อมก่อน แต่ไม่ควร parallel ทุกอย่างหาก B ต้องใช้ผล A จริง

หลัง mutation ต้องตอบให้ได้ว่า cache ใด stale และใครเป็นเจ้าของ invalidation สำหรับ deployment หลาย instance ต้องคิดต่อว่า tag หรือ cache state ประสานข้ามเครื่องอย่างไร ไม่เช่นนั้นผู้ใช้แต่ละเครื่องอาจเห็นข้อมูลคนละเวอร์ชัน

04ตอบให้เห็นการออกแบบ Boundary

อ่านเอกสารทางการ: Next.js Server และ Client Components