Waterfall xảy ra khi request sau chỉ bắt đầu sau khi request trước xong, dù chúng độc lập với nhau.
Với Suspense, nguyên nhân phổ biến là component con chỉ được render (và mới bắt đầu fetch) sau khi component cha đã có dữ liệu.
// waterfall: Comments only mounts after Post resolves
<Suspense fallback={<Skeleton />}>
<Post id={id}>
<Comments postId={id} />
</Post>
</Suspense>Cách sửa:
1. Khởi động request song song ở cấp trên, truyền promise xuống thay vì để con tự fetch:
const postPromise = getPost(id)
const commentsPromise = getComments(id) // starts immediately, not after post
<Suspense fallback={<Skeleton />}>
<Post promise={postPromise} />
<Suspense fallback={<CommentsSkeleton />}>
<Comments promise={commentsPromise} />
</Suspense>
</Suspense>2. Đặt boundary theo vùng nội dung, không bọc cả trang bằng một Suspense — phần nào có dữ liệu trước thì hiện trước.
3. Nếu dữ liệu con thật sự phụ thuộc dữ liệu cha (cần post.authorId mới lấy được author), waterfall là tất yếu; giảm bằng cách để backend trả gộp trong một endpoint.
Cách kiểm chứng khi phỏng vấn hỏi "làm sao biết": mở tab Network, nhìn biểu đồ waterfall — các thanh xếp bậc thang là dấu hiệu, xếp chồng song song là đã đúng.