Tối ưu hóa các truy vấn cơ sở dữ liệu trong Next.js 15 với Cache và Prisma
Lấy dữ liệu một cách hiệu quả trong ứng dụng Next.js là rất quan trọng để cải thiện hiệu suất. Với Next.js 15 và React 18, chúng ta có thể tận dụng chức năng cache để tối ưu hóa các truy vấn cơ sở dữ liệu và tránh các truy vấn lặp lại không cần thiết.
Trong bài viết này, chúng ta sẽ khám phá:
- Tại sao caching lại quan trọng
- Cách sử dụng cache với Prisma
- Triển khai một hàm cache để lấy bài viết trong Next.js 15
- Ví dụ sử dụng trong một trang Next.js 15
Tại sao nên sử dụng cache
cho các truy vấn cơ sở dữ liệu?
Khi truy vấn cơ sở dữ liệu trong một React Server Component hoặc một API route của Next.js, mục tiêu là giảm thiểu các truy vấn dư thừa để giảm tải cho cơ sở dữ liệu và cải thiện hiệu suất.
Chức năng cache sẽ ghi nhớ kết quả của truy vấn, vì vậy các lần gọi lại với cùng tham số sẽ trả về kết quả đã được cache thay vì thực hiện một truy vấn mới.
Lợi ích của việc sử dụng cache
với Prisma
- Giảm thiểu các truy vấn cơ sở dữ liệu trùng lặp: Cache giúp lưu trữ kết quả của các truy vấn, tránh việc phải gọi lại cơ sở dữ liệu cho những dữ liệu đã được truy vấn trước đó.
- Cải thiện hiệu suất của server: Bằng cách giảm số lượng truy vấn cơ sở dữ liệu, server sẽ ít phải xử lý hơn, từ đó hiệu suất được cải thiện.
- Tăng tốc độ phản hồi trong Server Components: Việc sử dụng cache giúp trả về dữ liệu nhanh hơn, cải thiện trải nghiệm người dùng và giảm độ trễ.
- Hoạt động mượt mà với Next.js và React 18: Cache dễ dàng tích hợp vào hệ sinh thái Next.js và React, mang lại một giải pháp tối ưu cho các ứng dụng hiện đại.
Triển khai cache
với Prisma trong Next.js 15
Hãy cùng tạo một hàm cache để lấy bài viết theo slug của nó.
Bước 1: Tạo hàm Cache
Chúng ta sẽ định nghĩa hàm getPostBySlug
bên trong một tệp tiện ích server (ví dụ: src/lib/posts.ts).
import db from "@/lib/db";
import { cache } from "react";
import { notFound } from "next/navigation";
import { type Prisma } from "@prisma/client";
/**
* Fetch a blog post by its slug and cache the result
*/
export const getPostBySlug = cache(
async <T extends Omit<Prisma.PostFindUniqueArgs, "where">>(
slug: string,
options?: T,
): Promise<Prisma.PostGetPayload<T>> => {
const post = await db.post.findUnique({
where: { slug },
...options,
});
if (!post) return notFound();
return post as Prisma.PostGetPayload<T>;
},
);
Bước 2: Sử dụng getPostBySlug
trong trang Next.js 15
Bây giờ, hãy sử dụng hàm này bên trong một Server Component trong Next.js.
import { getPostBySlug } from "@/lib/posts";
export const dynamic = "force-dynamic"; // Ensures the page revalidates
export default async function PostPage({ params }: { params: { slug: string } }) {
const post = await getPostBySlug(params.slug);
return (
<main className="max-w-3xl mx-auto p-6">
<h1 className="text-4xl font-bold">{post.title}</h1>
<p className="text-gray-600">{post.publishedAt}</p>
<article className="mt-6">{post.content}</article>
</main>
);
}
Những lưu ý quan trọng
1. Vô hiệu hóa Cache (Cache Invalidation)
Chức năng cache lưu trữ dữ liệu trong suốt vòng đời của yêu cầu. Nếu dữ liệu cập nhật thường xuyên, hãy sử dụng revalidatePath() để làm mới cache một cách thủ công.
2. Sử dụng cache trong Server Components
Cache chỉ khả dụng trong môi trường server, nghĩa là nó sẽ không hoạt động trong các client components.
3. Best Practice khi kết nối cơ sở dữ liệu
Đảm bảo rằng Prisma được cấu hình đúng với kết nối pooling khi sử dụng trong môi trường serverless (ví dụ: Vercel, AWS Lambda).
Kết luận
Việc sử dụng cache trong Next.js 15 với Prisma giúp cải thiện hiệu suất đáng kể bằng cách giảm thiểu các truy vấn cơ sở dữ liệu dư thừa. Phương pháp này là lý tưởng để cache các bài viết blog, hồ sơ người dùng, hoặc dữ liệu thường xuyên được truy cập trong môi trường server-side.
Cảm ơn các bạn đã theo dõi!
All rights reserved