Bài 24.5: Bài tập thực hành SSR

Bài 24.5: Bài tập thực hành SSR
Chào mừng các bạn đến với bài thực hành quan trọng về Server-Side Rendering (SSR) trong chuỗi bài học Lập trình Web Front-end của chúng ta! Sau khi đã cùng nhau khám phá các khái niệm lý thuyết về SSR, đã đến lúc chúng ta xắn tay áo và đưa kiến thức đó vào thực tế.
Thực hành là cách tốt nhất để nắm vững và hiểu sâu bất kỳ công nghệ nào. Với SSR, việc thực hành sẽ giúp bạn thấy rõ sự khác biệt về hiệu suất và SEO mà nó mang lại so với Client-Side Rendering (CSR) truyền thống.
SSR: Nhắc Lại Nhanh
Nhắc lại một chút, SSR là quá trình render (dựng) giao diện người dùng trên máy chủ trước khi gửi về trình duyệt của người dùng. Điều này trái ngược với CSR, nơi trình duyệt nhận về một file HTML gần như trống rỗng và JavaScript sẽ chịu trách nhiệm dựng toàn bộ giao diện sau đó.
Lợi ích chính của SSR bao gồm:
- Cải thiện SEO: Các Search Engine Bot dễ dàng thu thập nội dung đã được render sẵn trong HTML.
- Tải trang ban đầu nhanh hơn: Người dùng thấy nội dung hiển thị sớm hơn vì máy chủ đã chuẩn bị sẵn HTML.
- Trải nghiệm tốt hơn trên các thiết bị cấu hình yếu: Giảm tải công việc xử lý JavaScript ở phía client.
Bài Tập Thực Hành Cốt Lõi: Lấy Dữ Liệu Phía Máy Chủ
Một trong những trường hợp sử dụng phổ biến và mạnh mẽ nhất của SSR là khi trang web cần hiển thị dữ liệu động từ một API hoặc cơ sở dữ liệu ngay khi tải trang. Thay vì chờ JavaScript ở trình duyệt gọi API, chúng ta sẽ để máy chủ làm việc đó.
Bài tập thực hành này sẽ tập trung vào kịch bản: Tạo một trang chi tiết bài viết (hoặc sản phẩm) mà nội dung của nó được lấy từ một API ngay trên máy chủ trước khi trang được render.
Chúng ta sẽ sử dụng Next.js, một framework React hỗ trợ SSR rất tốt, để thực hiện bài tập này.
Thực Hiện Với Next.js và getServerSideProps
Trong Next.js, hàm getServerSideProps
là cánh cửa để bạn thực hiện SSR cho dữ liệu động. Hàm này sẽ chạy trên máy chủ mỗi khi có yêu cầu (request) đến trang đó. Dữ liệu trả về từ hàm này sẽ được truyền làm props
cho component trang.
Hãy cùng xem một ví dụ cụ thể: Tạo một trang hiển thị chi tiết của một bài viết dựa vào ID trên URL (/posts/1
, /posts/2
, v.v.).
Tạo file trang: Trong thư mục
pages
, tạo một thư mục conposts
, và bên trongposts
, tạo một file[id].tsx
(hoặc.jsx
). Dấu ngoặc vuông[]
trong tên file cho Next.js biết đây là một route động, nơiid
sẽ là giá trị từ URL.Viết Component Trang: Đây là component React sẽ nhận dữ liệu từ
getServerSideProps
và hiển thị nó.// pages/posts/[id].tsx import React from 'react'; interface Post { id: number; title: string; body: string; } interface PostDetailProps { post: Post; } const PostDetail: React.FC<PostDetailProps> = ({ post }) => { if (!post) { // Xử lý trường hợp không tìm thấy post (sẽ được handle bởi getServerSideProps) return <div>Bài viết không tồn tại.</div>; } return ( <div> <h1>{post.title}</h1> <p>{post.body}</p> {/* Bạn có thể hiển thị thêm thông tin khác của post ở đây */} </div> ); }; export default PostDetail;
Giải thích: Component
PostDetail
là một component React bình thường. Nó nhận một prop có tên làpost
(kiểuPost
). Nó kiểm tra xempost
có tồn tại không rồi hiển thị tiêu đề và nội dung bài viết.Viết Hàm
getServerSideProps
: Đây là phần quan trọng nhất của bài thực hành SSR này.// pages/posts/[id].tsx (Tiếp theo sau phần export default PostDetail) import { GetServerSideProps } from 'next'; // Import kiểu dữ liệu export const getServerSideProps: GetServerSideProps = async (context) => { const { id } = context.params as { id: string }; // Lấy ID từ URL try { // Gọi API để lấy dữ liệu bài viết dựa trên ID const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`); // Kiểm tra nếu response không thành công (ví dụ: 404 Not Found) if (!response.ok) { return { notFound: true, // Next.js sẽ hiển thị trang 404 }; } const post = await response.json(); // Chuyển đổi response sang JSON // Trả về dữ liệu làm props cho component trang return { props: { post, }, }; } catch (error) { console.error("Lỗi khi lấy dữ liệu bài viết:", error); // Xử lý lỗi: Có thể trả về trang lỗi hoặc hiển thị thông báo return { notFound: true, // Ví dụ: trả về 404 nếu có lỗi fetch }; } };
Giải thích:
export const getServerSideProps
: Đây là quy ước của Next.js. Hàm này phải được export.async (context)
: Hàm này là bất đồng bộ (async) và nhận một đối tượngcontext
.context
chứa thông tin về request, bao gồm cả các tham số từ URL động (params
).const { id } = context.params
: Chúng ta truy cập vàoparams
trongcontext
để lấy giá trịid
từ URL (ví dụ: nếu URL là/posts/123
thìid
sẽ là"123"
).await fetch(...)
: Thực hiện việc gọi API đến endpoint giả định (jsonplaceholder.typicode.com
). Việc này diễn ra trên máy chủ.if (!response.ok)
: Kiểm tra mã trạng thái HTTP. Nếu không phải 2xx, có nghĩa là có lỗi (ví dụ ID không tồn tại trả về 404). Chúng ta trả về{ notFound: true }
để Next.js tự động hiển thị trang 404 mặc định.await response.json()
: Phân tích dữ liệu JSON nhận được từ API.return { props: { post } }
: Đây là kết quả cuối cùng. Next.js nhận đối tượng này và truyền{ post: postData }
làm props cho componentPostDetail
.
Chạy Thử và Quan Sát Kết Quả
- Khởi chạy ứng dụng Next.js: Chạy lệnh
npm run dev
hoặcyarn dev
trong terminal. - Mở trình duyệt: Truy cập vào các URL như
/posts/1
,/posts/5
,/posts/10
. Bạn sẽ thấy nội dung bài viết tương ứng được hiển thị. Thử một ID không tồn tại, ví dụ/posts/9999
, bạn sẽ thấy trang 404. - Quan sát Sức Mạnh của SSR:
- Xem Nguồn Trang (View Page Source): Click chuột phải vào trang đang hiển thị và chọn "View Page Source" (hoặc tương đương). Đây là điểm mấu chốt! Bạn sẽ thấy toàn bộ nội dung bài viết (tiêu đề, nội dung) nằm ngay trong mã nguồn HTML mà trình duyệt nhận được. Điều này chứng tỏ máy chủ đã render nội dung.
- Kiểm tra tab Network: Mở DevTools (F12), chuyển sang tab "Network", và tải lại trang (Ctrl+R hoặc Cmd+R). Chọn dòng request đầu tiên (thường là file HTML của trang). Trong tab "Preview" hoặc "Response", bạn cũng sẽ thấy mã HTML đã chứa nội dung.
- Tốc độ tải ban đầu: So sánh (trong tưởng tượng hoặc thực tế) với một trang CSR phải chờ JavaScript tải, thực thi, rồi mới gọi API và render. Với SSR, nội dung hiển thị ngay lập tức khi HTML được phân tích.
Những Điều Rút Ra Từ Bài Thực Hành
Qua bài tập đơn giản này, bạn đã thực sự trải nghiệm SSR:
- Bạn thấy cách hàm
getServerSideProps
chạy trên máy chủ. - Bạn hiểu cách lấy dữ liệu trước khi component render.
- Bạn quan sát được kết quả: nội dung được nhúng sẵn trong HTML đầu tiên, mang lại lợi ích về SEO và hiệu suất.
- Bạn nhận ra
getServerSideProps
phù hợp với dữ liệu cần cập nhật trên mỗi request (ví dụ: dữ liệu người dùng đăng nhập, kết quả tìm kiếm, chi tiết bài viết thay đổi thường xuyên).
Mở Rộng Bài Tập (Tùy Chọn)
Để củng cố kiến thức, bạn có thể thử mở rộng bài tập này:
- Hiển thị thêm thông tin khác của bài viết (ví dụ: user ID).
- Xử lý lỗi hiển thị trên trang nếu API trả về lỗi khác 404.
- Kết hợp lấy dữ liệu từ nhiều API khác nhau trong
getServerSideProps
. - Thử nghiệm với việc truyền dữ liệu khác (ví dụ: một danh sách bình luận cho bài viết).
Bài tập thực hành SSR với getServerSideProps
trong Next.js là bước đệm cực kỳ quan trọng để bạn hiểu cách xây dựng các ứng dụng web hiệu năng cao và thân thiện với SEO. Hãy thử nghiệm, quan sát và đặt câu hỏi để nắm vững kỹ thuật này nhé!
Comments