
TL;DR: Next.js App Router mặc định lưu trữ dữ liệu rất mạnh mẽ. Điều này rất tốt cho hiệu suất nhưng lại gây khó chịu khi dữ liệu của bạn không được cập nhật. Bạn cần hiểu bốn lớp bộ nhớ đệm: Request Memoization, Data Cache, Full Route Cache và Router Cache để kiểm soát luồng dữ liệu của ứng dụng một cách có thể dự đoán được.

Nếu bạn đã từng cập nhật cơ sở dữ liệu nhưng ứng dụng Next.js của bạn vẫn hiển thị dữ liệu cũ, bạn không đơn độc đâu. Hầu hết các nhà phát triển tiếp cận việc lưu trữ dữ liệu một cách phản ứng: cái gì chậm thì thêm bộ nhớ đệm; cái gì cũ thì xóa đi. Điều này không hiệu quả trong Next.js vì có nhiều bộ nhớ đệm hoạt động đồng thời, thường là không biết về nhau.
Hãy cùng phân tích các lớp này, cách kiểm soát chúng và cách ngừng "đấu tranh" với framework.
Request Memoization là bộ nhớ đệm bị hiểu lầm nhiều nhất trong Next.js vì nó trông giống như một bộ nhớ đệm dữ liệu bền vững, nhưng thực ra không phải. Trong một lần render máy chủ duy nhất, nếu bạn gọi fetch() với cùng một URL và các tùy chọn nhiều lần trên các component khác nhau, Next.js sẽ loại bỏ các bản sao thành một yêu cầu HTTP duy nhất.

Điều này chỉ tồn tại trong suốt thời gian của một yêu cầu duy nhất. Nó không tồn tại qua nhiều người dùng hoặc tải lại trang. Đây là điều cho phép bạn tìm nạp dữ liệu trong Layouts và Pages của mình một cách độc lập mà không phải lo lắng về các truy vấn N+1.
// Both components call the same URL: only ONE HTTP request is made
async function Header() {
const user = await fetch('https://api.example.com/me').then(r => r.json());
return <header>Welcome, {user.name}</header>;
}
async function Sidebar() {
const user = await fetch('https://api.example.com/me').then(r => r.json());
return <aside>Profile: {user.avatar}</aside>;
}
Nếu bạn không sử dụng fetch() (ví dụ: gọi trực tiếp cơ sở dữ liệu bằng Prisma hoặc Drizzle), bạn phải tự ghi nhớ các truy vấn của mình bằng cách sử dụng hàm cache() của React để đạt được việc loại bỏ trùng lặp tương tự.
Data Cache là thứ khiến các nhà phát triển bất ngờ khi chuyển từ Pages router. Theo mặc định, Next.js App Router lưu trữ tất cả các lệnh gọi fetch() vô thời hạn trên máy chủ. Điều này tồn tại qua các yêu cầu và triển khai trừ khi bị vô hiệu hóa rõ ràng.

Nếu bạn đang xây dựng một bảng điều khiển cần dữ liệu thời gian thực, bạn phải từ chối hành vi này. Bạn có thể thực hiện điều này một cách chi tiết cho mỗi lần tìm nạp bằng cách sử dụng no-store.
// Opt out of caching entirely for real-time data
const liveData = await fetch('https://api.example.com/metrics', {
cache: 'no-store'
});
Đối với dữ liệu cập nhật định kỳ, hãy sử dụng Tái tạo tĩnh tăng dần (ISR) bằng cách xác định khoảng thời gian tái xác thực.
// Cache data but refresh it in the background every 60 seconds
const cachedData = await fetch('https://api.example.com/stats', {
next: { revalidate: 60 }
});
Các ứng dụng doanh nghiệp thường dựa vào Tái xác thực theo yêu cầu. Bạn lưu trữ dữ liệu vô thời hạn (force-cache) nhưng kích hoạt tái xác thực qua Webhooks khi CMS hoặc cơ sở dữ liệu cập nhật. Điều này đảm bảo cập nhật tức thì mà không lãng phí tài nguyên nền. Sử dụng revalidatePath('/route') hoặc revalidateTag('my-tag') trong Server Actions hoặc Route Handlers của bạn để xóa các mục bộ nhớ đệm cụ thể.
Full Route Cache lưu trữ payload HTML và React Server Component (RSC) cho các tuyến tĩnh tại thời điểm build. Khi người dùng truy cập tuyến, máy chủ ngay lập tức trả về payload đã lưu trữ thay vì render lại. Bộ nhớ đệm này tự động bị vô hiệu hóa khi bạn tái xác thực dữ liệu bằng cách sử dụng revalidatePath hoặc revalidateTag.

Router Cache là một bộ nhớ đệm trong bộ nhớ phía máy khách. Khi người dùng điều hướng ứng dụng của bạn, Next.js lưu trữ các phân đoạn tuyến đã truy cập. Điều này có nghĩa là việc quay lại một trang đã truy cập trước đó là tức thì. Tuy nhiên, nó cũng có nghĩa là các thay đổi phía máy khách có thể không phản ánh ngay lập tức trừ khi bạn gọi rõ ràng router.refresh() để buộc trình duyệt tìm nạp payload RSC mới nhất từ máy chủ.
Hiểu cách bốn lớp này giao thoa sẽ giúp bạn kiểm soát hoàn toàn hiệu suất và độ tươi mới của dữ liệu. Đừng đoán xem bộ nhớ đệm nào đã cũ, hãy xác định rõ ràng các chiến lược dữ liệu của bạn và để Next.js xử lý phần việc nặng nhọc.
Đọc thêm: Nếu bạn đang gặp khó khăn với SSR, hãy xem hướng dẫn này về cách khắc phục Lỗi Hydration của Next.js.
Làm sạch log AI CLI, tạo biểu thức cron, giải mã JWT và tính quyền chmod offline.

Hướng dẫn chuẩn production toàn diện cho Next.js App Router: Ranh giới Server Components, caching nâng cao, streaming với Suspense, Server Actions, connection pooling và kiến trúc route cho enterprise.
Đọc tiếp
Hướng dẫn cấu trúc thư mục Next.js App Router đã được kiểm nghiệm trong thực tế. Tìm hiểu về route groups, private folders, colocation vs FSD, và tải xuống một template doanh nghiệp có khả năng mở rộng.
Đọc tiếp
Nắm vững kiến trúc bộ nhớ đệm của Next.js App Router: ghi nhớ yêu cầu fetch, vô hiệu hóa bộ nhớ đệm dữ liệu với revalidateTag và revalidation ISR theo yêu cầu.
Đọc tiếp