Sequential (tuần tự) xảy ra khi một await phải đợi cái trước xong mới chạy — gây waterfall, cộng dồn latency.
const user = await getUser(id) // 200ms
const posts = await getPosts(user.id) // +200ms — bắt buộc tuần tự vì cần user.idNếu thật sự phụ thuộc (posts cần user.id) thì tuần tự là đúng.
Parallel (song song) khi các request độc lập — khởi động cùng lúc rồi cùng await:
const userP = getUser(id)
const statsP = getStats(id)
const [user, stats] = await Promise.all([userP, statsP]) // ~max, không cộng dồnPreload pattern xử lý tình huống component con mới cần data nhưng ta muốn bắt đầu fetch sớm (trước khi render tới component đó):
export const preload = (id: string) => { void getItem(id) }
// component cha:
preload(id) // khởi động fetch ngay, không await
// ... render việc khác, component con sau đó getItem(id) trúng cache (React cache dedupe)Lưu ý: fetch được React/Next dedupe + cache trong một render, nên gọi preload rồi gọi lại getItem không tạo 2 request.
Mục tiêu: loại waterfall vô ích, giữ tuần tự chỉ khi có phụ thuộc thật.
Sequential happens when one await must finish before the next runs — causing a waterfall that sums latencies.
const user = await getUser(id) // 200ms
const posts = await getPosts(user.id) // +200ms — necessarily sequential, needs user.idIf there's a real dependency (posts need user.id), sequential is correct.
Parallel when requests are independent — kick them off together, then await:
const userP = getUser(id)
const statsP = getStats(id)
const [user, stats] = await Promise.all([userP, statsP]) // ~max, not summedPreload pattern handles the case where a child component needs the data but you want to start the fetch early (before render reaches that child):
export const preload = (id: string) => { void getItem(id) }
// parent:
preload(id) // start the fetch now, don't await
// ... render other work; the child later calls getItem(id) and hits the cache (React cache dedupes)Note: fetch is deduped + cached within a render by React/Next, so calling preload then getItem won't make two requests.
Goal: eliminate needless waterfalls, keep sequential only when there's a genuine dependency.