Giới thiệu
Next.js 15 đã mang đến nhiều cải tiến về hiệu năng và khả năng mở rộng, đặc biệt khi được kết hợp với TypeScript. Trong môi trường yêu cầu tốc độ tải trang nhanh và SEO mạnh mẽ, việc tối ưu Server‑Side Rendering (SSR) và áp dụng cơ chế cache hợp lý là yếu tố quyết định. Bài viết này sẽ phân tích chi tiết cách cấu hình SSR, thiết lập cache ở mức server và client, đồng thời đưa ra các mẫu code thực tiễn.
Cấu trúc SSR cơ bản trong Next.js
getServerSideProps với TypeScript
Hàm getServerSideProps chạy trên server mỗi khi người dùng yêu cầu trang. Khi sử dụng TypeScript, ta khai báo kiểu cho context để nhận được tính năng tự hoàn thiện và giảm lỗi runtime.
export async function getServerSideProps(context: GetServerSidePropsContext) {
const { params } = context;
const res = await fetch(`https://api.example.com/posts/${params?.id}`);
const post = await res.json();
return {
props: { post },
// Revalidate after 60 seconds (ISR)
revalidate: 60,
};
}Trong đoạn code trên, thuộc tính revalidate cho phép Next.js thực thi Incremental Static Regeneration (ISR) ngay cả khi sử dụng SSR, giảm tải cho server trong các truy vấn lặp lại.
Tối ưu cache với Cache‑Control trong API Route
Trong các API route, chúng ta có thể thiết lập tiêu đề Cache‑Control để trình duyệt và CDN lưu trữ phản hồi trong khoảng thời gian mong muốn. Điều này đặc biệt hữu ích cho dữ liệu tĩnh hoặc ít thay đổi.
export const config = {
api: {
bodyParser: false,
},
};
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
// Set long‑term cache for static assets
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
// … fetch data …
res.json({ data });
}Tiêu đề trên chỉ định rằng nội dung có thể được lưu trữ trong cache của CDN trong một năm và không cần tái xác thực cho đến khi hết thời gian.
Sử dụng Middleware để kiểm soát cache ở mức global
Middleware trong Next.js cho phép xử lý yêu cầu trước khi đến route hoặc API. Chúng ta có thể thêm tiêu đề Cache‑Control cho mọi GET request, đồng thời bảo vệ các request không GET khỏi việc cache.
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// Add cache header only for GET requests
if (request.method === 'GET') {
response.headers.set('Cache-Control', 'public, s-maxage=120, stale-while-revalidate=60');
}
return response;
}Với s-maxage và stale‑while‑revalidate, CDN sẽ phục vụ bản cache ngay lập tức, đồng thời gửi yêu cầu cập nhật nền trong khi người dùng vẫn nhận dữ liệu cũ.
Data fetching ở client với SWR và TypeScript
SWR (stale‑while‑revalidate) là thư viện fetcher nhẹ, hỗ trợ tái‑định dạng dữ liệu và tự động cập nhật khi có thay đổi. Kết hợp với TypeScript, chúng ta có thể xác định kiểu dữ liệu trả về, giúp IDE và công cụ lint bắt lỗi sớm.
import useSWR from 'swr';
import type { Post } from '@/types';
const fetcher = (url: string) => fetch(url).then(res => res.json());
export function usePost(id: string) {
const { data, error, isLoading } = useSWR(`/api/posts/${id}`, fetcher, {
revalidateOnFocus: false,
dedupingInterval: 30000,
});
return { data, error, isLoading };
}
Tham số dedupingInterval ngăn các request trùng lặp trong khoảng thời gian xác định, giảm tải mạng và server.
Kết luận
Bằng cách kết hợp getServerSideProps có hỗ trợ ISR, thiết lập tiêu đề Cache‑Control trong API Route, sử dụng Middleware để áp dụng quy tắc cache toàn cục, và khai thác SWR cho fetch phía client, chúng ta đạt được tối ưu hiệu năng toàn diện cho một ứng dụng Next.js 15. Nếu bạn muốn nắm bắt toàn bộ quy trình phát triển, bao gồm các kỹ thuật nâng cao như Server Actions, Prisma ORM và NextAuth, hãy Tham khảo khóa học "Lập trình Front-End với NextJS + TypeScript" tại đây.




.png)



