Server Components của Next.js 14 giúp giảm kích thước bundle khoảng 60% và đẩy thời gian first-paint xuống dưới 200ms trên một trang blog điển hình, nghĩa là người dùng thấy nội dung nhanh hơn và các công cụ tìm kiếm nhận được HTML đã được render đầy đủ.
Bản phát hành mới này đảo ngược mô hình thực thi mặc định cho các ứng dụng React được xây dựng bằng Next.js. Thay vì mọi component đều được gửi đến trình duyệt như trước đây, giờ đây các nhà phát triển có thể đánh dấu các phần của UI là “Server Components” để chúng chỉ chạy ở backend. Mã nguồn của các component đó không bao giờ tới được client, giúp trình duyệt chỉ phải xử lý những phần cần tính tương tác.
Tại sao sự thay đổi này lại quan trọng
Các nhà phát triển React từ lâu đã phải vật lộn với ba vấn đề đan xen: một loạt các yêu cầu mạng (network requests), các bundle JavaScript cồng kềnh và tốc độ tải trang chậm chạp. Những vấn đề này cũng gây hại cho SEO vì HTML ban đầu gửi đến các trình thu thập dữ liệu (crawlers) thường trống rỗng, buộc các bot tìm kiếm phải chờ đợi quá trình client-side hydration. Next.js 14 giải quyết nguyên nhân gốc rễ bằng cách chuyển toàn bộ các tác vụ nặng về dữ liệu ra khỏi client.
Server Components khác với mô hình cũ như thế nào
- Server Components – Thực thi trên server, lấy dữ liệu (fetch data), giao tiếp với cơ sở dữ liệu và xuất ra HTML thuần túy. JavaScript của chúng không bao giờ truyền qua mạng.
- Client Components – Ở lại trong trình duyệt và xử lý các tương tác UI như nhấp chuột vào nút, gửi biểu mẫu, hoặc bất kỳ component nào sử dụng React state hoặc effects.
Framework này thực thi sự phân chia này bằng một chỉ thị đơn giản. Việc thêm use client vào đầu tệp sẽ báo cho Next.js biết rằng component đó chỉ dành cho client-side. Bất kỳ thứ gì không có dấu hiệu đó sẽ mặc định là một Server Component.
Những con số thực tế
Một thử nghiệm nhanh trên một trang blog cá nhân đã minh họa tác động này. Sau khi chuyển việc fetch dữ liệu vào một Server Component và để server render danh sách dưới dạng HTML tĩnh, bundle JavaScript đã giảm 60% và trang web được render trong chưa đầy 200ms.
Một mô hình phân lớp thực tế
- Lớp dưới cùng (Server) – Lấy dữ liệu từ các API hoặc cơ sở dữ liệu. Giữ mọi logic riêng tư tại đây; nó sẽ không bao giờ rời khỏi server.
- Lớp giữa (Server) – Chuyển đổi dữ liệu thô thành mã HTML thuần túy. Lớp này vẫn có thể sử dụng cú pháp JSX của React nhưng chỉ chạy trên server.
- Lớp trên cùng (Client) – Chèn các widget nhỏ, biệt lập để tạo tính tương tác. Các ví dụ điển hình là nút “thích”, biểu mẫu bình luận hoặc menu thả xuống yêu cầu state.
Tuân theo hệ thống phân cấp này giúp phần lớn ứng dụng luôn nhẹ nhàng trong khi vẫn giữ được cảm giác năng động mà người dùng mong đợi.
Các bước bạn có thể thử ngay hôm nay
- Quét mã nguồn của bạn để tìm các component chỉ sử dụng
useEffectđể fetch dữ liệu. - Trích xuất lời gọi fetch vào một Server Component mới và để nó trả về mã markup đã được render.
- Tạo một client component tối giản (thêm
use clientở đầu) cho bất kỳ thành phần tương tác nào còn lại. - Chạy lại trình phân tích bundle (bundle analyzer); bạn sẽ thấy kích thước giảm đi đáng kể.
Tránh việc rải use client ở khắp mọi nơi. Nếu một component không phụ thuộc vào React state, context hoặc các lifecycle hooks, hãy để nó là một Server Component. Bạn càng giữ nhiều mã nguồn tránh xa client, dung lượng tải xuống càng nhỏ và trang web càng nhanh.
Bài học rút ra: Bằng cách chuyển việc lấy dữ liệu và render nặng sang server, Next.js 14 cho phép bạn gửi đi ít JavaScript hơn nhiều, cung cấp HTML đã được render đầy đủ ngay lập tức và duy trì tính tương tác ở những nơi thực sự cần thiết. Kết quả là một trải nghiệm web nhanh hơn, gọn nhẹ hơn, mang lại lợi ích cho cả người dùng và các công cụ tìm kiếm.
