Caching, Pages, Components
// NextJs는 공격적인 캐싱을 수행합니다
// ⭐️요청 메모이제이션 (서버 측)
// 'GET'메소드에서만 발생✅
// NextJs는 동일한 구성의 데이터 요청을 저장합니다.
// 이는 불필요한 중복 데이터 페칭을 피할 수 있습니다.
// 캐시는 요청 기간 동안만 지속됩니다.
// --> 예를 들어, HTTP 헤더를 통해 Cache-Control이나 Expires 등의 지시자를 사용하여 캐시의 유효 기간을 설정
// --> 동일한 구성(예: 동일한 URL, 동일한 쿼리 매개변수 등)으로 데이터 요청이 발생할 경우, Next.js는 이전에 동일한 요청에 대해 이미 페칭된 데이터를 캐싱합니다.
// ex)
// fetch('http://api.com', {
// next: {
// // next속성은 nextjs에서만 존재
// revalidate: 50, //요청이후 50초 이전의 재요청은 요청하지않고 이전 캐시된 데이터를 반환
// tags: ['products','title'] // 태그 등록도 가능
// },
// });
// ✅ GET method이고, server action안에 있지않으며, cookies나 headers를 사용하지않으면
// fetch request는 자동으로 cache됨
// 🔥 cf) 만약 위의 조건에 해당하지않는 fetch구문이라면 자동 캐싱기능이 작동하지않으므로,
// 캐싱기능을 사용하고자 한다면 unstable_cache의 첫번째 인자에 해당 fetch구문을 함수화하여 넣어 사용하면됨
// ⭐️데이터 캐시 (서버 측)
// NextJs는 데이터를 페칭하여 재사용하며, 이는 revalidate될 때까지 유지됩니다.
// 이는 데이터 소스에 대한 불필요한 요청을 피하고, 애플리케이션 속도를 높입니다.
// 캐시는 revalidate될 때까지 지속됩니다(수동으로 또는 설정된 시간 후에).
// revalidatePath()를 사용하여 데이터 재사용을 금지하고, 다시 페칭을 트리거할 수 있습니다.
// --> 새로고침해야 데이터의 변경사항이 적용될때는, 데이터 캐시때문. 이때에 캐시의 revalidate가 필요
// ⭐️전체 경로 캐시 (서버 측)
// NextJs는 빌드 시점✅(배포 전에 애플리케이션을 준비하는 과정)에 렌더링된 HTML과 RSC(React Server Component)를 저장합니다.
// 이는 불필요한 HTML 렌더 사이클 및 데이터 페칭을 피할 수 있습니다.
// 관련 데이터 캐시가 revalidate될 때까지 캐시가 지속됩니다.
// ⭐️라우터 캐시 (클라이언트 측 캐싱)
// NextJs는 브라우저 메모리에 RSC 페이로드를 저장합니다.
// 이는 서버 요청 없이 매우 빠른 페이지 전환✅을 보장합니다.
// --> 페이지 전환 시 브라우저의 메모리에 React Server Component (RSC) 페이로드를 저장하여 빠른 페이지 전환을 가능하게 하는 기능
// Next.js는 페이지를 렌더링할 때, 필요한 React Server Component (RSC)의 결과를 클라이언트 측에 저장합니다.
// 이 RSC 페이로드는 페이지를 처음 로드할 때 서버에서 생성되어 클라이언트로 전송되며, 브라우저의 메모리에 저장됩니다.
// 다음에 방문하는 페이지가 이전에 로드한 페이지와 동일한 RSC를 사용할 경우, 브라우저는 서버에 새로운 데이터를 요청하지 않고 메모리에 저장된 RSC를 사용하여 페이지를 즉시 렌더링
// -> 라우터 캐시는 보통 브라우저의 세션 동안 유지되므로, 사용자가 브라우저를 닫거나 세션을 종료할 때까지 유지
// ✅ 사용자가 한 페이지를 방문한 후 다른 페이지로 이동할 때 이전 페이지의 상태를 일시적으로 캐싱
// cf) 다만, 사용자가 한 페이지를 방문한 후 제3의 페이지로 이동하면 이전 페이지의 캐시는 지워집니다
// ⭐️ 정적페이지(Static Pages) , 동적페이지(Dynamic Pages)
// Nextjs에서 'npm run build'로 빌드 할때, 생성된 페이지들은 정적페이지, 동적페이지로 구분됨
// 1. 정적페이지
// 이러한 페이지는 빌드 시점✅에서 HTML 파일로 생성됩니다. (🔥사전에 빌드된 HTML파일)
// 이 HTML 파일들은 정적 리소스로 서버에 의해 직접 제공될 수 있습니다.
// 클라이언트에서도 해당 HTML 파일들을 가져와서 렌더링할 수 있습니다.
// 예를 들어, 블로그 포스트 목록이나 정적 컨텐츠 페이지 등이 여기에 속합니다.
// 🔥--> 기본적으로 서버에서 HTML 파일을 미리 생성하고, 해당 파일을 클라이언트에 제공하기 때문에 CSR(Client-Side Rendering)은 사용되지 않습니다. 정적 페이지는 SSR✅(Static Site Generation)을 통해 생성된 고정된 콘텐츠를 제공
// 2. 동적페이지
// 동적 페이지는 보통 라우팅 시에 요청된 경로나 파라미터에 따라 서버 측에서✅ 요청에 따라 동적으로✅ HTML을 생성하여 클라이언트에게 전달하는 페이지
// 이는 서버 사이드 렌더링✅(SSR, Server-Side Rendering) 또는 서버 컴포넌트로 구현될 수 있습니다.
// 🔥동적 페이지와 SSR: 동적 페이지는 서버 측에서 요청 시점에 동적으로 HTML을 생성합니다. 이는 SSR을 통해 구현될 수 있습니다.
// 🔥동적 페이지와 CSR: 동적 페이지는 사용자의 상호작용✅에 따라 데이터가 업데이트되거나 새로운 페이지가 생성될 수 있습니다. 이 경우 CSR을 통해 브라우저에서 JavaScript를 사용하여 동적으로 페이지를 렌더링합니다.
// ⭐️-->> CSR✅을 하려면 해당 페이지를 'use client' 클라이언트 컴포넌트✅로 변경해야함
// 예를 들어, 사용자가 요청한 특정 상품의 상세 페이지나 블로그의 개별 포스트 페이지 등이 동적 페이지에 해당할 수 있습니다.
// Next.js에서는 라우터를 통해 동적 페이지를 처리하며, 이 페이지들은 서버에서 초기 렌더링되고 클라이언트에 전달됩니다.
// 동적 페이지는 사용자가 요청할 때마다 동적으로 데이터를 가져와서 렌더링되기 때문에, URL 경로와 매핑되는 데이터를 통해 다양한 컨텐츠를 보여줄 수 있습니다.
// ⭐️ 서버컴포넌트, 클라이언트컴포넌트
// 1. 서버 컴포넌트
// 서버 사이드 실행: 서버 컴포넌트는 서버에서 실행되므로, 클라이언트 측에서 JavaScript가 로드되기 전에 서버에서 HTML을 렌더링합니다. 이로 인해 초기 로딩 속도가 개선되고 SEO(Search Engine Optimization)에 유리합니다.
// 렌더링 위치: 클라이언트 컴포넌트는 클라이언트 측에서 동적으로 HTML을 생성하는 반면, 서버 컴포넌트는 서버에서 동적으로 HTML을 생성합니다. 따라서 서버 컴포넌트는 초기 렌더링에 필요한 데이터를 서버에서 가져와 적용할 수 있습니다.
// 동적 요청 처리: 서버 컴포넌트는 클라이언트 사이드에서 발생하는 동적 요청을 처리할 수 있습니다. 예를 들어 사용자가 인터랙션으로 인해 데이터를 업데이트하거나 새로운 정보를 요청할 때, 서버 컴포넌트는 이를 처리하고 새로운 HTML을 동적으로 생성하여 클라이언트에 전달합니다.
// 장점 : 서버사이드렌더링(SSR), 데이터 접근 및 처리(서버에서 필요한 데이터를 직접 접근하고 처리 가능)
// 2. 클라이언트 컴포넌트 - ⭐️Next.js에서 클라이언트 사이드 렌더링을 통해 동적으로 페이지를 생성하고 관리하는 방식을 의미
// 클라이언트 컴포넌트는 브라우저에서 실행되는 컴포넌트로, 서버 사이드 렌더링(SSR)의 성능 문제를 해결하고자 만들어졌습니다.
// 서버에서는 HTML을 생성하지만, 클라이언트 사이드에서는 컴포넌트의 인터랙션과 동적 로딩을 처리합니다.
// 🔥 cf)초기 페이지 로딩 시에는 서버 측에서 미리 렌더링된 HTML을 받아와서 화면에 보여줍니다. 이 과정은 서버 사이드 렌더링(SSR)을 통해 이루어집니다
// ✅ 이후 클라이언트에서는 이 HTML을 기반으로 JavaScript와 함께 앱을 초기화하고 상호작용을 지속적으로 처리합니다.(서버로부터 받은 초기 HTML에 이후 상호작용으로 CSR방식의 리렌더링)
// 각 클라이언트 컴포넌트는 독립적으로 서버 및 클라이언트 사이에서 데이터를 가져오고 렌더링합니다.
// ✅ -->> 클라이언트 컴포넌트는 서버에서 초기 렌더링된 HTML을 받아오고, 브라우저에서 JavaScript가 로드된 후에 클라이언트에서 동적으로 HTML을 생성하고 업데이트합니다(hydrate)
// 장점: 인터랙티브 요소 처리, 실시간 업데이트⭐️