React의 Server Components 이해하기

제이미·2025년 1월 24일

리액트

목록 보기
17/19
post-thumbnail

오늘은 React 18에서 도입되었던 Server Components에 대해서 파헤쳐보자!

Server Components란?

: UI 컴포넌트를 서버에서 렌더링해 클라이언트로 전송하는 방식
(서버와 클라이언트 역할을 나눠서 빠르고 효율적인 애플리케이션 개발 가능)

이 Server Components는 서버 환경에서 동작하고, 브라우저가 아니라 서버에서 필요한 데이터를 처리하고 UI를 렌더링한다.
(이 렌더링 된 결과는 HTML 또는 JSON 형태로 클라이언트로 전송됨 - 해당 서버 컴포넌트는 자바스크립트를 거의 처리하지 않고도 컨텐츠를 표시할 수 있음!)

Server Components는 어떤 것들을 할까?

이 친구는 주로 데이터 처리, API 호출 등 백엔드 작업 같은 일들을 서버에서 수행한다.
: 이렇기에 이 컴포넌트 내부에는 정적인 코드만 포함되어야 한다!

또한, 브라우저에서 실행되지 않기에 브라우저 전용 기능(Ex: window, document, localStorage, etc) 은 포함할 수 없다.

이에 반해, Client Components는 UI 이벤트 처리와 상호작용을 담당하게 되는 것이다.
(Client Components 파일 최상단에 'use client'를 작성해줌으로써, 해당 파일은 클라이언트 컴포넌트라는 것을 명시)

위 코드 예시에서 만약 서버 컴포넌트인 ProductList에서 매핑된 product에 이벤트를 등록하고 싶다면?

위에서도 말했듯이, 서버 컴포넌트에서는 이벤트 핸들러를 직접 사용할 수 없기 때문에!
product에 이벤트 핸들러를 등록하려면 해당 요소를 클라이언트 컴포넌트로 위임하여 처리할 수 있다.
(위의 예시의 ProductItem을 위임해주는 것이다 - 이는 클라이언트 컴포넌트!)

그럼 서버 컴포넌트와 SSR은 같은 개념인가?

정답은 X!

이 둘은 같지 않다.
목적과 동작 방식에 차이가 있음! (그 중 몇 가지를 알아보쟈)
서버에서 실행하는 것은 둘이 동일함!

1. 렌더링 방식

페이지 요청 시 서버 컴포넌트는 서버에서 일부 컴포넌트를 렌더링해 클라이언트와 병합하지만,
SSR은 서버에서 HTML 전체를 렌더링 하고 브라우저로 전송한다.
(페이지 전체를 서버에서 렌더링하는 SSR과는 달리 서버 컴포넌트는 특정 컴포넌트만 서버에서 렌더링!)

2. Hydration

서버 컴포넌트는 클라이언트 컴포넌트만 Hydration을 진행한다면, SSR은 모든 컴포넌트가 Hydration을 거친다.

3. 목적

서버 컴포넌트는 번들 크기 축소와 서버 로직을 활용을 위해 쓰여진다.
반면, SSR은 초기 로딩 속도 개선과 SEO를 위해 활용이 되는 것(Server components도 이와 같은 강점이 있긴 함)!

4. 브라우저 전용 기능

서버 컴포넌트는 위에서 언급했듯이 브라우저 전용 기능(window, document, localStorage 등)을 사용할 수 없지만,
SSR은 사용이 가능하다!

Server Components와 SSR은 위와 같은 차이점들이 존재한다!

Server Components와 Next.js은 연관이 깊다

Next.js은 기본적으로 SSR을 지원하는 프레임워크이다.
하지만, 서버 컴포넌트 개념이 React 18에서 도입되고 Next.js가 이것을 지원하게 되었음!
(Next.js는 서버 컴포넌트는 선택적으로 사용할 수 있는 렌더링 방식)

Next.js의 SSR 코드는 어떻게 생겼을까?

(SSR 코드는 pages 디렉토리 하위에서 작성 - 페이지 전체를 렌더링하기 때문)

일단, 서버의 데이터가 필요할 때는 해당 페이지에서 getServerSideProps 함수를 이용해서 데이터를 패치한 후 페이지 컴포넌트의 props로 건네줘야 한다.
(해당 페이지의 요청이 들어왔을 때마다 실행)

props로 받은 데이터를 페이지 컴포넌트에서 활용

Next.js에서의 Server Components 코드는?

(서버 컴포넌트 코드는 pages 하위에 있어야 하는 SSR 코드와는 달리, app 디렉토리 내에 작성해주면 됨)
Ex) app/components/ServerComponent.js

서버 컴포넌트
: 데이터를 바로 패치해 사용하고 있삼

클라이언트 컴포넌트
: 해당 파일의 상단에 'use client' 명시로 클라이언트 컴포넌트임을 명시해주고, 이벤트 처리를 함!

pages 디렉토리에 존재하는 원하는 페이지에 이 Server Component와 Client Compoent를 결합해 넣어주면 된다!

그럼, Server Components의 장점과 단점에는 어떤 것들이 있을까?

먼저 서버 컴포넌트의 장점!

1. 초기 로딩 성능 향상

: 서버에서 렌더링된 HTML을 클라이언트로 전달하기 때문에 초기 페이지 로딩 시간이 빨라진다.
(클라이언트 측에서 렌더링 할 필요 없음)

2. SEO 향상

: 서버에서 렌더링된 HTML검색 엔진 크롤러가 쉽게 처리하기 때문에 SEO가 향상 된다.

3. 서버 리소스 활용

: 서버에서 직접 데이터를 가져오고 처리하기에, 클라이언트가 데이터를 요청하지 않는 대신 서버에서 데이터를 바로 렌더링한다.

4. 데이터 보안

: 클라이언트에 해당 데이터가 노출이 되지 않기 때문에 민감한 데이터나 API 키가 안전하게 처리된다.

그렇다면 단점은?

1. 클라이언트 사이드 상호작용 제한

: 서버 컴포넌트는 동적 상호작용을 처리할 수 없기에, 별도의 클라이언트 컴포넌트 사용이 필요하다.

2. 리렌더링 성능

: 서버 컴포넌트는 클라이언트에서 상태 변화가 발생할 때마다 서버에 다시 요청을 보내는 방식으로 동작할 수 있기 때문에...?! 빈번한 리렌더링이 필요한 경우가 있을 수 있어 성능 저하가 일어날 수 있다!
(홀리몰리~~ 그러네요)
-> 상태가 자주 변경되거나 동적인 컨텐츠가 많을 경우에 서버에 과부하를 일으킬 수 있음

3. 서버 의존성 증가

: 서버에서 직접 데이터를 가져오고 렌더링하기에 서버 의존성이 커진다.
-> 서버에 문제가 있으면 서비스 중단이 발생할 수 있음

4. 서버 측 렌더링 속도

: 서버 컴포넌트가 많아질수록 서버에서의 렌더링 시간이 길어질 수 있고, 서버 리소를 많이 사용하는 경우 성능 저하로 이어질 수 있다.

그렇다면, 서버 컴포넌트와 자동 코드 스플리팅의 연관성은 뭘까?

* 자동 코드 스플리팅이란?
: 애플리케이션의 전체 자바스크립트 파일을 한꺼번에 로드하는 대신필요한 파일만 동적으로 로드하는 최적화 기법!

서버 컴포넌트는 자연스럽게 자동 코드 스플리팅을 지원한다!

서버 컴포넌트를 사용하면, 클라이언트와 서버 간에 코드가 자동으로 분리되어서 필요한 코드만 클라이언트에 전달된다.
(서버에서 실행되는 코드는 클라이언트로 전송되지 않음)

그래서 클라이언트 측에서는 최소한의 코드만 로드하게 되니까 페이지 로딩 시간이 최적화 되고 성능이 향상 되는 것!
-> 효율적인 리소스 관리 가능

오늘 Server Components에 대한 이해는 여기까지이다!

Next.js를 이용해서 서버 컴포넌트와 클라이언트 컴포넌트를 구분해서 구현하는 방법을 언능 적용하고 싶다 :)

profile
프론트엔드 개발하다 궁금할 때

0개의 댓글