
Next.js 16์ ์๋ก์ด ์บ์ฑ ๊ธฐ๋ฅ์ ํ๋ก์ ํธ์ ์ ์ฉํ์ฌ ์ฑ๋ฅ์ ๊ฐ์ ํจ. ๊ธฐ์กด์ fetch ๊ธฐ๋ฐ ๋ฐ์ดํฐ ๋ก๋ฉ ๋ฐฉ์์์ ์๋ฒ ์ก์ ๊ณผ
'use cache'๋๋ ํฐ๋ธ๋ฅผ ํ์ฉํ ์ต์ ํ๋ ๊ตฌ์กฐ๋ก ์ ํํ์.
๊ธฐ์กด์๋ ํด๋ผ์ด์ธํธ์์ ์ง์ API๋ฅผ ํธ์ถํ๋ ๋ฐฉ์์ ์ฌ์ฉํ์ผ๋, ์ด๋ฅผ ์๋ฒ ์ก์ ์ผ๋ก ์ ํํ๊ณ ์บ์ฑ์ ์ ์ฉํจ.
๋ณ๊ฒฝ ์ (app/page.tsx):
const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
const Page = async () => {
if (!BASE_URL) return null;
const res = await fetch(`${BASE_URL}/api/events`);
const { events } = await res.json();
// ...
}
๋ณ๊ฒฝ ํ (app/page.tsx):
import { getAllEventsCached } from "@/lib/actions/event.actions";
const Page = async () => {
const events = await getAllEventsCached();
// ...
}
๐ก ์ฃผ์ ๊ฐ์ ์
- ํ๊ฒฝ ๋ณ์ ์์กด์ฑ ์ ๊ฑฐ
- ๋ถํ์ํ ๋คํธ์ํฌ ์ค๋ฒํค๋ ๊ฐ์
- ์๋ฒ ์ฌ์ด๋์์ ์ง์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ์ผ๋ก ์๋ต ์๋ ํฅ์
lib/actions/event.actions.ts์ ์๋ก์ด ์บ์๋ ์๋ฒ ์ก์
์ ์ถ๊ฐํจ:
export const getAllEventsCached = async () => {
'use cache';
try {
await connectDB();
const events = await Event.find().sort({ createdAt: -1 }).lean();
return JSON.parse(JSON.stringify(events));
} catch (error) {
console.error("Error fetching all events:", error);
throw error;
}
};
๐ฅ ํต์ฌ ํฌ์ธํธ
'use cache'๋๋ ํฐ๋ธ: Next.js 16์ ์๋ก์ด ๊ธฐ๋ฅ์ผ๋ก, ํจ์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์๋์ผ๋ก ์บ์ฑ (next.config.ts์์ cacheComponents ๋ฅผ true ๋ก ํด์ผํจ.).lean(): Mongoose์ lean() ๋ฉ์๋๋ก ์์ JavaScript ๊ฐ์ฒด ๋ฐํ, ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๊ฐ์JSON.parse(JSON.stringify()): MongoDB ObjectId์ Date ๊ฐ์ฒด๋ฅผ ์ง๋ ฌํํ์ฌ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์์๋ ์์ ํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํ๋๋ก ์ฒ๋ฆฌ
์ฝ๋ ๊ตฌ์กฐ ๊ฐ์ ์ ์ํด ์ด๋ฒคํธ ๋ชฉ๋ก ๋ ๋๋ง ๋ก์ง์ ๋ณ๋ ์ปดํฌ๋ํธ๋ก ์ถ์ถํจ.
components/EventList.tsx:
import EventCard from "@/components/EventCard";
import { IEvent } from "@/database";
export default async function EventList({ events }: { events: IEvent[] }) {
return (
<ul className="events">
{events && events.length > 0 ? (
events.map((event: IEvent) => (
<li key={event.title} className="list-none">
<EventCard {...event} />
</li>
))
) : (
<p className="text-center text-gray-500">No events found at the moment.</p>
)}
</ul>
);
}
์ด๋ฅผ ํตํด ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ ์ป์:
- ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ
- ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ ๊ตฌ์กฐ
- ๋ ๋์ ์ฝ๋ ๊ฐ๋ ์ฑ
- ๋น ์ํ ์ฒ๋ฆฌ ๊ฐ์
next.config.ts์ ์บ์ฑ ๊ด๋ จ ์ค์ ์ ์ถ๊ฐํจ:
const nextConfig: NextConfig = {
cacheComponents: true,
images: {
remotePatterns: [
// ...
]
}
};
โ๏ธ cacheComponents ์ต์
Next.js 16์์ ๊ธฐ๋ฅ์ผ๋ก, ์ปดํฌ๋ํธ ๋ ๋ฒจ์ ์บ์ฑ์ ํ์ฑํํจ. ์ด๋ฅผ ํตํด ์๋ฒ ์ปดํฌ๋ํธ์ ๋ ๋๋ง ๊ฒฐ๊ณผ๋ ์บ์ํ ์ ์์.
'use cache'๋ Next.js 16์์ ์๋กญ๊ฒ ๋์
๋ ๊ธฐ๋ฅ์ผ๋ก, ๋ค์๊ณผ ๊ฐ์ ํน์ง์ด ์์:
const events = await Event.find().sort({ createdAt: -1 }).lean();
.lean() ๋ฉ์๋๋:
- Mongoose Document ๋์ ์์ JavaScript ๊ฐ์ฒด ๋ฐํ
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ฝ 30-40% ๊ฐ์
- ์ง๋ ฌํ ์ฑ๋ฅ ํฅ์
- ์ฝ๊ธฐ ์ ์ฉ ๋ฐ์ดํฐ์ ์ต์ ํ
โ ๏ธ ์ฃผ์์ฌํญ
.lean()์ ์ฌ์ฉํ๋ฉด Mongoose์ virtuals, getter/setter, ๋ฉ์๋ ๋ฑ์ ์ฌ์ฉํ ์ ์์. ์์ํ๊ฒ ๋ฐ์ดํฐ๋ง ์ฝ์ด์ฌ ๋ ์ฌ์ฉํด์ผ ํจ.
๊ธฐ์กด์๋ app/page.tsx์์ ์ง์ ์ด๋ฒคํธ ๋ชฉ๋ก์ ๋ ๋๋งํ์ผ๋, EventList ์ปดํฌ๋ํธ๋ก ๋ถ๋ฆฌํจ์ผ๋ก์จ:
ํ์ฌ ๊ตฌํ๋ ์บ์ฑ์ ๊ธฐ๋ณธ์ ์ธ ์์ค์ด๋ฉฐ, ์ถ๊ฐ๋ก ๊ณ ๋ คํ ์ ์๋ ๊ฐ์ ์ฌํญ:
Revalidation ์ ๋ต ์๋ฆฝ
์ธ๋ถํ๋ ์บ์ฑ
๋ชจ๋ํฐ๋ง
Next.js 16์ ์๋ก์ด ์บ์ฑ ๊ธฐ๋ฅ์ ํ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
์ ์ฑ๋ฅ์ ํฌ๊ฒ ๊ฐ์ ํจ. 'use cache' ๋๋ ํฐ๋ธ์ ์๋ฒ ์ก์
์ ์กฐํฉ์ ๋งค์ฐ ๊ฐ๋ ฅํ๋ฉฐ, ๊ธฐ์กด์ ๋ณต์กํ ์บ์ฑ ์ ๋ต์ ๋จ์ํํ ์ ์์.
ํนํ ๋ค์๊ณผ ๊ฐ์ ์ ์์ ์๋ฏธ๊ฐ ์์: