# 전 Next.js 의 미래가 마음에 들어요 : 정말 멋있어지고 있어요

> Clean Markdown view of GeekNews topic #19391. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=19391](https://news.hada.io/topic?id=19391)
- GeekNews Markdown: [https://news.hada.io/topic/19391.md](https://news.hada.io/topic/19391.md)
- Type: news
- Author: [xguru](https://news.hada.io/@xguru)
- Published: 2025-02-24T10:02:01+09:00
- Updated: 2025-02-24T10:02:01+09:00
- Original source: [tigerabrodi.blog](https://tigerabrodi.blog/i-like-the-future-of-nextjs)
- Points: 14
- Comments: 3

## Summary

Next.js의 미래 방향은 매우 흥미롭고, 특히 PPR(Partial Pre-rendering)과 새로운 세분화된 캐시 시스템이 주목받고 있습니다. 새로운 캐시 시스템은 `next.config.js`에서 실험적으로 활성화할 수 있으며, 다양한 만료 시간과 재검증 주기를 설정할 수 있는 캐시 프로필을 정의할 수 있습니다. 또한, `use cache` 선언을 통해 파일, 컴포넌트, 함수 수준에서 캐싱을 쉽게 적용할 수 있으며, 태그 기반 캐싱을 통해 특정 데이터 그룹의 캐시를 관리하고 무효화할 수 있습니다.

## Topic Body

- Next.js의 미래 방향이 흥미로움  
- Server Actions에 대한 이슈가 있었지만 React 19의 `useOptimistic`, `useFormStatus`로 개선 가능성이 보임  
  - Remix의 `useFetcher` 방식도 좋은 DX를 제공함  
- Next.js의 PPR(Partial Pre-rendering)과 새로운 granular 캐시 시스템이 특히 돋보임  
- 전반적으로 매우 긍정적인 인상을 받음  
  
### The Big Picture  
- `next.config.js`에서 새로운 캐시 시스템을 실험적으로 활성화할 수 있음  
- 캐시 프로필을 정의해 다양한 만료 시간과 재검증 주기를 설정할 수 있음  
```ts  
// next.config.js  
const config = {  
  experimental: {  
    // 새로운 캐싱 시스템 활성화. 이제 코드에서 `use cache` 사용 가능   
    dynamicIO: true,   
    // 선택사항: 캐시 프로파일 설정   
    cacheLife: {  
      blog: {  
        stale: 3600, // 클라이언트 캐시 유지: 1시간  
        revalidate: 900, // 서버에서 새로고침: 15분  
        expire: 86400, // 최대 수명: 1일  
      },  
    },  
  },  
};  
```  
  
### `use cache` 기본 사용법  
- 파일, 컴포넌트, 함수 수준에서 `"use cache"` 선언을 통해 캐싱 가능함  
- 코드 예시에서 `use cache`를 추가해 쉽게 캐시를 적용할 수 있음  
- `cacheTag`, `revalidateTag` 등을 활용해 원하는 시점에 캐시 무효화가 가능함  
  
```ts  
// 1. 파일 단위 캐싱  
"use cache";  
export default function Page() {  
  return &lt;div&gt;Cached Page&lt;/div&gt;;  
}  
  
// 2. 컴포넌트 단위 캐싱  
export async function PriceDisplay() {  
  "use cache";  
  const price = await fetchPrice();  
  return &lt;div&gt;${price}&lt;/div&gt;;  
}  
  
// 3. 함수 단위 캐싱  
export async function getData() {  
  "use cache";  
  return await db.query();  
}  
```  
  
### 태그 기반 캐싱  
```ts  
import { unstable_cacheTag as cacheTag, revalidateTag } from 'next/cache';  
  
// 특정 데이터 그룹 캐싱  
export async function ProductList() {  
  'use cache';  
  cacheTag('products');  
  const products = await fetchProducts();  
  return &lt;div&gt;{products}&lt;/div&gt;;  
}  
  
// 데이터 변경 시 캐시 무효화  
export async function addProduct() {  
  'use server';  
  await db.products.add(...);  
  revalidateTag('products');  
}  
```  
  
### 사용자 정의 Cache 프로필  
- `unstable_cacheLife`를 사용해 `next.config.js`에서 정의한 캐시 프로필을 불러올 수 있음  
- 코드 내부에서 선언된 프로필명(예: `"blog"`)을 사용해 캐시 정책을 적용함  
  
```ts  
import { unstable_cacheLife as cacheLife } from "next/cache";  
  
export async function BlogPosts() {  
  "use cache";  
  cacheLife("blog"); // 미리 정의한 블로그 캐시 프로필 사용  
  return await fetchPosts();  
}  
```  
  
### 중요하지만 간과할 수 있는 사항  
  
#### 캐시 키 자동 생성  
- 컴포넌트의 `props`와 `arguments`가 자동으로 캐시 키에 포함됨  
- 직렬화 불가능한 값(함수 등)은 "수정 불가능한 참조" 형태로 처리됨  
```js  
export async function UserCard({ id, onDelete }) {  
  "use cache";  
  // id는 캐시 키에 포함  
  // onDelete는 전달되지만 캐싱에는 영향을 주지 않음  
  const user = await fetchUser(id);  
  return &lt;div onClick={onDelete}&gt;{user.name}&lt;/div&gt;;  
}  
```  
  
#### 동적 콘텐츠와 캐시 콘텐츠의 혼합  
- 캐시된 콘텐츠 내부에 동적 콘텐츠를 자식으로 전달해 혼합해 사용할 수 있음  
- `cacheTag` 배열을 지정해 여러 태그를 동시에 적용하고 무효화할 수 있음  
```ts  
export async function CachedWrapper({ children }) {  
  "use cache";  
  const header = await fetchHeader();  
  return (  
    &lt;div&gt;  
      &lt;h1&gt;{header}&lt;/h1&gt;  
      {children} {/* 동적 콘텐츠는 그대로 유지 */}  
    &lt;/div&gt;  
  );  
}  
```  
  
```js  
export async function ProductPage({ id }) {  
  "use cache";  
  cacheTag(["products", `product-${id}`, "featured"]);  
  // 이 태그들 중 어떤 것을 사용해도 무효화 가능  
}  
```  
  
#### 캐싱 계층 구조  
- 최상위 레벨에서 `"use cache"`를 선언하면 해당 영역 전체가 캐시됨  
- 특정 부분(예: Suspense를 사용한 동적 섹션)은 캐싱 영역에서 제외할 수 있음  
```ts  
"use cache";  
export default async function Page() {  
  return (  
    &lt;div&gt;  
      &lt;CachedHeader /&gt;  
      &lt;div&gt;  
        &lt;Suspense fallback={&lt;Loading /&gt;}>  
          &lt;DynamicFeed /&gt; {/* 동적 콘텐츠 */}  
        &lt;/Suspense&gt;  
      &lt;/div&gt;  
    &lt;/div&gt;  
  );  
}  
```  
  
#### 타입 안전성  
- 캐시 키와 캐시 프로필 등 문자열을 상수로 관리해 매직 스트링 사용을 줄일 수 있음  
- React Query의 패턴처럼 태그를 생성해주는 방식을 사용하면 편리함  
```ts  
// 상수로 캐시 프로필 키를 관리  
export const CACHE_LIFE_KEYS = {  
  blog: "blog",  
} as const;  
  
const config = {  
  experimental: {  
    cacheLife: {  
      [CACHE_LIFE_KEYS.blog]: {  
        stale: 3600,  
        revalidate: 900,  
        expire: 86400,  
      },  
    },  
  },  
};  
```  
  
#### 캐싱 태그를 효율적으로 관리하는 방법  
- **React Query 스타일의 태그 팩토리 패턴 적용**  
```ts  
export const CACHE_TAGS = {  
  blog: {  
    all: ["blog"] as const,  
    list: () => [...CACHE_TAGS.blog.all, "list"] as const,  
    post: (id: string) => [...CACHE_TAGS.blog.all, "post", id] as const,  
    comments: (postId: string) =>  
      [...CACHE_TAGS.blog.all, "post", postId, "comments"] as const,  
  },  
} as const;  
  
// 캐싱 태그 설정  
function tagCache(tags: string[]) {  
  cacheTag(...tags);  
}  
  
// 사용 예제  
export async function BlogList() {  
  "use cache";  
  tagCache(CACHE_TAGS.blog.list());  
}  
```

## Comments



### Comment 35348

- Author: schang124
- Created: 2025-03-03T11:14:29+09:00
- Points: 1

SEO 가 중요해서 SSR 이 필요한 상황에서만 Next.js 또는 Remix 같은 framework 를 사용하는게 좋은 것 같습니다.   
  
특히 B2B 비지니스 제품이나 back office 같이 SEO 가 중요하지 않은 서비스에 Next.js 를 도입하는 것은 신중할 필요가 있다고 생각합니다. Next.js 가 강제하는 인터페이스나 복잡도가 개발 생산성을 낮출 수 있기 때문입니다.   
  
개인적으로 SEO 가 불필요한 경우는 Vite + React 가 개발 생산성과 유연성 등에서 훨씬 좋다고 생각합니다.

### Comment 35105

- Author: [hidden]
- Created: 2025-02-25T18:47:52+09:00
- Points: 1

[숨김 처리된 댓글입니다]

### Comment 35069

- Author: 9vvin
- Created: 2025-02-25T10:17:41+09:00
- Points: 1

next.js는 13 이후로 참쓸만해졌는데 최근엔 정말정말 맘에 듭니다. 풀스택 웹개발 기술 스택의 사실상 표준이 될 것 같습니다.
