Vì mọi prop truyền từ Server Component xuống Client Component đều bị serialize và gửi kèm trong RSC payload. Server Component tiết kiệm được JavaScript, nhưng không tự lọc dữ liệu.
Mô hình sai hay gặp:
tsx
// Server Component
const products = await db.product.findMany() // 100 rows, full columns
return <ProductGrid products={products} /> // Client ComponentProductGrid chỉ hiển thị id, name, price, thumbnail nhưng payload mang theo description, metadata, internalNotes, createdBy của cả 100 dòng. Dữ liệu này đi hai lần: một lần trong HTML, một lần trong RSC payload để hydrate.
Cách xử lý:
- Chỉ chọn cột cần dùng ngay ở tầng truy vấn (
selecttrong Prisma, liệt kê cột trong SQL). Đây là thay đổi hiệu quả nhất và cũng làm truy vấn nhanh hơn. - Ánh xạ sang DTO trước khi truyền qua ranh giới client, để hình dạng dữ liệu gửi đi là chủ ý chứ không phải mặc định.
- Đẩy ranh giới client xuống thấp hơn. Nếu chỉ nút "Thêm vào giỏ" cần tương tác, để
ProductGridlà Server Component và chỉ nút đó là Client Component nhậnproductId. - Đừng truyền nguyên object ORM. Nó thường mang theo trường quan hệ và thuộc tính nội bộ.
Rủi ro kèm theo cần nói rõ trong phỏng vấn: payload này nằm trong mã nguồn trang, ai cũng đọc được. Truyền nguyên bản ghi user xuống là rò rỉ dữ liệu dù giao diện không hiển thị các trường đó.