1. Giới thiệu App Router & Server Components
Từ Next.js 13+, App Router (src/app/) là cách tổ chức route mới, thay cho Pages Router. Mặc định, mọi component trong thư mục app/ đều là React Server Components (RSC).
Tại sao Server Components lại quan trọng?
- Không làm tăng bundle JS: Các thư viện nặng (như parse markdown, format ngày tháng, query database) được thực thi trên server và không bao giờ bị gom vào bundle JavaScript gửi xuống client.
- Truy cập Backend trực tiếp: Bạn có thể query PostgreSQL hoặc gọi nội bộ microservice ngay trong component mà không cần qua API route trung gian.
// src/app/projects/page.tsx
// Đây là Server Component theo mặc định
import { db } from '@/lib/db';
export default async function ProjectsPage() {
// Query trực tiếp DB tại Server
const projects = await db.project.findMany({
orderBy: { createdAt: 'desc' }
});
return (
<div className="grid grid-cols-3 gap-6">
{projects.map((project) => (
<div key={project.id} className="p-4 bg-dark-secondary rounded-lg border border-dark-border">
<h3 className="text-white font-fira">{project.title}</h3>
<p className="text-text-secondary text-sm mt-2">{project.description}</p>
</div>
))}
</div>
);
}2. Các tầng cache trong Next.js 14
Next.js 14 có bốn tầng cache. Phần này đi qua hai tầng phía server, nơi bạn kiểm soát trực tiếp nhất:
2.1. Request Memoization
Nếu bạn gọi cùng một hàm fetch() với cùng URL nhiều lần trong một chu kỳ render (chẳng hạn ở cả Layout và Page), Next.js sẽ tự động memoize kết quả để chỉ thực hiện 1 network request duy nhất.
2.2. Data Cache (Persistent Server Cache)
Dữ liệu trả về từ fetch được lưu giữ liên tục trên server cho đến khi bạn chủ động revalidate:
// Tự động làm mới cache sau mỗi 3600 giây (1 giờ) - ISR
const res1 = await fetch('https://api.example.com/products', {
next: { revalidate: 3600 }
});
// Hoặc sử dụng Tag-based Revalidation cho dữ liệu thời gian thực
const res2 = await fetch('https://api.example.com/cart', {
next: { tags: ['cart-data'] }
});3. Khi nào nên dùng 'use client'?
Chỉ thêm chỉ thị 'use client' ở trên cùng của file khi component cần:
- Dùng các React Hook như
useState,useEffect,useRef,useCallback. - Gắn các event listener (
onClick,onChange). - Sử dụng Browser API (
window,localStorage,navigator).
Nguyên tắc chung
Để Server Component ở tầng trên cùng (Layout/Page) và đẩy Client Component xuống các component lá nhỏ nhất (Button, Modal, Input).
