본문 바로가기
Resource/웹 프론트엔드

[Next.js] Next.js의 클라이언트, 서버 컴포넌트 / 렌더링 전략 / Time

by 우창욱 2024. 1. 28.

 

클라이언트 / 서버 컴포넌트의 동작 방식

 

Next.js 어플리케이션에서 페이지를 요청받게 되면, 해당 페이지를 서버에서 렌더링 합니다. 일반적으로 페이지는 클라이언드, 서버 컴포넌트로 이루어져 있으며 각 컴포넌트들은 서버에서 pre-rendering 된 후에 브라우저로 보내집니다.

 

서버 컴포넌트의 경우 서버에서 모든 코드가 실행된 후 반환된 HTML이 클라이언트로 전송됩니다. 이 컴포넌트는 일반적으로

초기 페이지 로딩 시에 사용되고, 데이터를 가져오거나 SEO(Search Engine Optimization)를 위해 사용됩니다.

 

 

클라이언트 컴포넌트도 마찬가지로 서버에서 초기 HTML을 생성하는데, HTML과 함께 브라우저에서 실행될 JS 파일(ex. 사용자 인터렉션)도 생성해서 클라이언트로 전송합니다. 이 과정에서 전송된 HTML과 JS 파일은 브라우저에서 실행됩니다. Next.js 는 `Hydration` 이라는 과정을 거치면서 서버에서 생성된 HTML을 브라우저에서 실행되는 JavaScript와 연결합니다. 즉 클라이언트 컴포넌트는 CSR(Client Side Rendering)를 거쳐 사용자에게 화면을 보여주게 됩니다.

 

서버 사이드 렌더링(SSR) 과정 중 클라이언트 컴포넌트 내에 있는 `console.log()`와 같은 코드가 실행되면 결과가 서버 측 터미널에도 출력됩니다. 이는 Next.js가 서버에서 클라이언트 컴포넌트를 렌더링하는 동안 JS 코드를 실행하기 때문입니다. 그 후, 페이지가 클라이언트로 전송되고, 페이지에 포함된 JS 코드가 클라이언트 사이드에서 실행될 때, 동일한 `console.log()` 코드가 다시 실행되어 브라우저의 콘솔에 출력됩니다. 이러한 이중 실행은 서버 사이드에서 생성된 HTML을 기반으로 하여 클라이언트 컴포넌트의 JavaScript를 활성화하는 과정에서 발생합니다. 그러나 중요한 점은, 클라이언트 컴포넌트의 JS 코드는 서버 사이드에서 렌더링되는 것이 아니라 초기 HTML 생성을 위해 실행되고, 실제 동적인 기능과 인터렉션은 클라이언트 사이드에서 이루어집니다.

 

Next.js의 빌드 타임, 런타임 / 런타임 환경

빌드 타임 (Build Time)

빌드 타임코드 컴파일, 번들링, 최적화 등의 단계를 포함한 프로덕션용 어플리케이션 코드를 준비하는 일련의 단계입니다. 즉, 빌드 타임(컴파일 타임)은 개발자가 코드를 컴파일 하는 시간입니다. `npm run build`와 같이 필요한 모든 정적 파일, 번들링, 최적화, 종속성 해결 등을 포함하는 어플리케이션 빌드를 생성하는 시간을 의미합니다.

런타임 (Run Time)

런타임어플리케이션 코드의 동적 실행시스템 리소스 활용을 포함하여 컴파일 또는 배포된 어플리케이션이 능동적으로 실행되고 동작하는 시간을 의미합니다. 즉, 런타임은 사용자가 어플리케이션 코드를 실행하는 시간이며 사용자 입력, 이벤트에 응답, 데이터 조작 / 엑세스, 외부 서비스 또는 API와의 상호 작용 등의 데이터 처리와 같은 사용자 상호작용을 처리하는 것입니다.

런타임 환경 (Run Time Environment, RTE)

런타임과 런타임 환경은 다릅니다. 런타임 환경은 프로그램이나 어플리케이션이 실행되는 동안 실행되는 특정 환경입니다. 프로그램의 실행을 지원하는 라이브러리, 서비스 또는 런타임 구성 요소 집합을 제공합니다. 브라우저가 아닌 환경에서 JavaScript를 실행할 수 있게 해주는 Node.js가 런타임 환경의 예시입니다.

 

Next.js에서는 'nodejs'와 'edge' 두 가지의 런타임 환경을 제공합니다. 아래와 같이 간단한 코드로 런타임 환경을 변경할 수 있습니다.

 

export const runtime = 'edge' // 'nodejs' (default) | 'edge'

 

Node.js 런타임 환경

모든 Node.js API 및 생태계에 엑세스 할 수 있는 기본 런타임 환경입니다.

Edge 런타임 환경

Node.js에서 제한된 Web API 기반 하위 집합을 지원하는 런타임 환경입니다.


Next.js의 렌더링 전략 (Rendering Strategies)

DALL-E가 그린 SSG, ISR, SSR

 

Next.js는 서버에서 렌더링할 수 있는 3가지의 전략을 제공합니다.

SSG (Static Site Generation)

SSG는 서버의 빌드 타임에 발생합니다. 빌드 프로세스 중에 콘텐츠가 생성되어 HTML, CSS, JavaScript로 변환되고 런타임 중에 서버와의 인터렉션이 필요하지 않습니다. 하지만 만약 파일에 업데이트가 발생한다면, 다시 빌드를 해야합니다. 블로그와 뉴스와 같은 웹 사이트들이 예시입니다.

 

생성된 정적 파일들은 CDN(Content Deliery Network)에 호스팅 된 다음 클라이언트로 전송됩니다. 정적 파일들이 CDN에 호스팅 된다는 것은, 전 세계에 분산된 서버 네트워크로 정적 파일들이 분산된다는 뜻이고, 사용자는 지리적으로 가장 가까운 서버에서 웹 사이트 콘텐츠를 볼 수 있게 되므로 로딩 시간이 단축되며 사용자 경험(UX)이 개선됩니다. 그리고 CDN은 여러 서버에 걸쳐 콘텐츠를 복제하기 때문에 하나의 서버에 문제가 생겨도 다른 서버가 콘텐츠를 제공할 수 있어서 웹 사이트의 가용성과 신뢰성을 높여줍니다.

 

또한 CDN은 자주 요청되는 콘텐츠를 캐시에 저장하여 빠른 로딩 시간을 제공하고 네트워크가 분산되어 있기 때문에 DDoS와 같은 보안 위협으로부터도 안전합니다.

ISG (Incremental Static Generation)

ISG는 전체 정적 페이지들을 재빌드 없이 업데이트 할 수 있게 하는 렌더링 전략입니다. ISR의 온디멘드(on-demand) 생성을 통해 특정 페이지가 필요할 때 생성하거나, 사용자의 요청에 따라 생성할 수 있습니다. 즉, 웹 사이트나 페이지의 특정 부분은 빌드 타임에 생성되고 다른 부분은 런타임에만 생성됩니다. 이는 요청된 페이지만 재생성하므로 빌드 타임을 감소시키고 웹사이트의 전반적인 성능을 향상시킵니다.

 

예시로는 기사 세부 정보 페이지에 SSG를 사용하고, 기사 목록을 표시하는 곳에서는 ISG를 적용하는 것이 있습니다.

SSR (Server Side Rendering)

동적 렌더링을 통해 각 요청에 대한 동적인 콘텐츠를 생성하여, 신선하고 인터렉티브 한 사용자 경험을 제공할 수 있습니다. SSR은 웹 사이트가 클라이언트와의 상호작용에 크게 의존하고 실시간 업데이트가 필요한 상황에서 훌륭한 전략입니다. 특히 인증(Authentication), 채팅 플랫폼과 같은 실시간 협업 어플리케이션, 편집 도구, 그리고 비디오 스트리밍 서비스에 적합합니다. 또한 서버가 모든 개별 요청에 대해서 코드를 실행하고, 필요한 HTML 파일을 생성하고, 클라이언트 측 상호작용을 위해 필요한 JS 코드와 함께 응답을 전달하는 무거운 서버 측 처리도 포함됩니다.

 

동적 특성으로 인해 콘텐츠 캐싱이 어려워지고, SSG, ISG에 비해 서버 부하가 증가하지만, 실시간 상호작용최신 콘텐츠를 제공할 수 있다는 이점으로 SSR은 어플리케이션 요구사항에 좋은 선택이 될 수 있습니다.