리액트 서버 컴포넌트(RSC) 논쟁: 혁신인가 퇴보인가? 커뮤니티 시각 분석

리액트 서버 컴포넌트(React Server Components)란 무엇일까요

이전에는 사용자가 리액트(React) 애플리케이션에 접속하면, 서버는 하나 이상의 자바스크립트(JavaScript) 파일 링크가 포함된 텅 빈 HTML 파일을 보내주는 것이 일반적이었습니다

그러면 브라우저(browser)는 이 HTML을 먼저 해석하고, 그 다음 자바스크립트(JavaScript) 파일들을 내려받아 클라이언트(client) 측에서 웹 페이지를 그려내는 방식이었죠

리액트 서버 컴포넌트(React Server Components, 이하 RSC)의 등장은 리액트(React)의 활동 범위를 서버 영역까지 확장시켰습니다

이름에서 알 수 있듯이, RSC는 리액트(React)의 서버(server) 측 컴포넌트(component)입니다

이 컴포넌트들은 오직 서버에서만 실행되며, 서버 측의 메서드(method)를 호출하거나 데이터베이스(database)에 접근하는 등의 작업을 할 수 있습니다

RSC는 서버에서 미리 렌더링(pre-rendering)을 마친 후, 그 결과물인 HTML을 클라이언트(client)에게 보냅니다

클라이언트(client)는 이 HTML을 받아서 화면에 표시하고 필요한 상호작용을 추가하는 하이드레이션(hydration) 과정을 거쳐 최종적으로 페이지를 완성합니다

이 방식의 가장 큰 장점은, 기존에 클라이언트(client) 측 자바스크립트(JavaScript) 파일에 포함되어야 했던 일부 코드를 서버에서 실행시킬 수 있다는 것입니다

덕분에 클라이언트(client)가 다운로드하고 처리해야 할 부담이 줄어들어, 애플리케이션(application)의 전반적인 성능과 반응 속도를 개선할 수 있습니다

"서버 자원을 최대한 활용하자"는 것이 RSC가 등장하게 된 가장 큰 동기입니다

다시 말해, 사용자 상호작용이 필요 없는 모든 것은 서버에 두는 것이 좋다는 아이디어인데요

리액트(React) 공식 문서에서는 마크다운(markdown) 콘텐츠를 렌더링(rendering)하는 아주 대표적인 예를 보여주었습니다

클라이언트 컴포넌트로 마크다운 렌더링하기

// 클라이언트 측에서 실행될 경우, 이 라이브러리들이 브라우저로 다운로드됩니다<br /><br />
import marked from 'marked'; // 약 35.9KB (압축 시 11.2KB)
import sanitizeHtml from 'sanitize-html'; // 약 206KB (압축 시 63.3KB)

function NoteWithMarkdown({text}) {
  // 마크다운 텍스트를 HTML로 변환하고, 혹시 모를 악성 코드를 제거합니다<br /><br />
  const html = sanitizeHtml(marked(text));
  // 변환된 HTML을 화면에 렌더링합니다<br /><br />
  return (/* HTML 렌더링 로직 */);
}

 
이 예제에서, 만약 클라이언트(client) 컴포넌트(component)로 렌더링(rendering)한다면, 사용자는 이 콘텐츠를 보기 위해 최소 200KB가 넘는 자바스크립트(JavaScript) 파일을 다운로드해야 합니다

하지만 여기서 다루는 마크다운(markdown) 콘텐츠는 사실 사용자와의 상호작용이 필요 없고, 사용자의 조작 때문에 내용이 업데이트될 일도 거의 없습니다

이는 RSC를 사용하기에 아주 적합한 상황이죠

만약 RSC를 사용한다면 어떻게 될까요

서버 컴포넌트로 마크다운 렌더링하기

// 서버 측에서만 실행되므로, 클라이언트 번들 크기에 영향을 주지 않습니다<br /><br />
import marked from 'marked'; // 번들 크기 0
import sanitizeHtml from 'sanitize-html'; // 번들 크기 0

function NoteWithMarkdown({text}) {
  // 서버에서 마크다운 변환 및 정제 작업을 수행합니다<br /><br />
  const html = sanitizeHtml(marked(text));
  // 변환된 HTML을 클라이언트로 전송합니다<br /><br />
  return (/* HTML 렌더링 로직 */);
}

 
필요한 라이브러리(dependency package)들은 서버에만 머무르고, 서버는 사용자에게 보여줄 최종 결과물(HTML)만 반환합니다

클라이언트(client) 측 번들 크기가 순식간에 200KB 이상 줄어드는 놀라운 효과를 볼 수 있습니다

여기까지는 커뮤니티의 주류 의견도 RSC에 대해 긍정적이었습니다

하지만 RSC의 특징을 기반으로 한 웹 프레임워크(web framework)인 넥스트JS(Next.js)가 공격적으로 새로운 기능들을 내놓기 시작하면서, 커뮤니티 내에서 의견 차이가 발생하기 시작했습니다

커뮤니티의 의견 대립

의견 대립의 가장 근본적인 원인은 리액트(React)가 '서버 측'이라는 개념을 도입했다는 점입니다

서버 컴포넌트(Server Components)와 클라이언트 컴포넌트(Client Components)는 명확한 차이점을 가집니다

  • 서버 컴포넌트(Server Components)는 useState, useEffect 같은 리액트 훅(React Hooks)을 사용할 수 없지만, 클라이언트 컴포넌트(Client Components)는 사용할 수 있습니다

  • 서버 컴포넌트(Server Components)는 브라우저(browser) API에 접근할 수 없지만, 클라이언트 컴포넌트(Client Components)는 모든 브라우저(browser) API 권한을 가집니다

  • 서버 컴포넌트(Server Components)는 서버 측 프로그램이나 API에 직접 접근할 권한이 있지만, 클라이언트 컴포넌트(Client Components)는 오직 요청(request)을 통해서만 일부 프로그램에 접근할 수 있습니다

넥스트JS(Next.js)가 v13 및 v14를 출시하면서, 리액트(React)에서는 아직 실험적인 버전(canary version)인 RSC를 넥스트JS(Next.js)가 정식 운영 환경(production environment)으로 가져왔습니다

컴포넌트(component) 파일 상단에 'use client''use server' 같은 지시어를 사용하는 방식이 점점 더 많은 사람들에게 논의되기 시작했죠

개발자들 사이에서는 이제 "두 개의 리액트(React)"가 존재한다는 말이 나오기 시작했고, 커뮤니티에서는 지난 몇 년간 리액트(React)가 진보했는지 아니면 오히려 퇴보했는지에 대한 논쟁이 벌어지기 시작했습니다

커뮤니티의 반대 목소리

저명한 소프트웨어 엔지니어, 캐시디 윌리엄스(Cassidy Williams)

그녀는 지난 2년간 리액트(React) 개발의 문제점들을 지적했습니다

  • "두 개의 리액트(React)"가 가져온 새로운 개념들은 대부분의 사람들에게 명확하고 이해하기 쉬운 지식이 아닙니다

    이러한 분열은 추가적인 혼란과 학습 장벽을 유발할 수 있습니다

  • 리액트(React)는 2022년 6월 이후 새로운 버전 릴리스(release)가 없었을 뿐만 아니라, 개발자들에게 상위 계층 프레임워크(framework) 사용을 권장하고 있습니다

    그런데 이 상위 프레임워크(framework)들은 RSC가 안정 버전으로 업그레이드되기를 기다리지 않고 RSC 기반의 기능들을 출시해버렸습니다

    (이는 거의 넥스트JS(Next.js)를 지목하는 발언입니다)

  • 최근 몇 년간 리액트(React) 팀의 일부 멤버들이 다른 상위 프레임워크(framework) 팀으로 합류했습니다

    그들은 버전 업데이트를 소홀히 했을 뿐만 아니라, 공식 문서 업데이트도 등한시하고 있습니다

리액트 쿼리(React Query) 개발자, 태너 린슬리(Tanner Linsley)

그 역시 리액트(React)의 발전 방향에 대한 우려와 불만을 표했습니다

  • 리액트(React)가 훅(Hooks)과 서스펜스(Suspense) API를 도입한 이후, 너무 소수의 특정 개념에 과도하게 집중하고 있습니다

    이러한 새로운 개념들이 기술적으로는 싱글 스레드(single-thread) UI API의 한계와 경계를 확장했을지 몰라도, 사용자에게 가치를 제공하는 자신의 일상적인 업무에는 거의 영향을 미치지 못했습니다

  • RSC의 출시를 보면, 리액트(React) 팀은 더 이상 클라이언트(client) 측 성능에 대해 예전만큼 강한 추구를 하지 않는 것 같습니다

지도 기술 및 시각화 기술 전문가, 톰 맥라이트(Tom MacWright)

그는 리액트(React) 생태계의 파편화를 비판했습니다

  • 현재 리액트(React) 업데이트는 매우 느립니다

    대신 쇼피파이(Shopify)의 투자를 받는 리믹스(Remix)와 버셀(Vercel)의 투자를 받는 넥스트JS(Next.js)라는 두 개의 상위 프레임워크(framework)가 치열하게 경쟁하고 있습니다

  • 리액트(React) 팀과 넥스트JS(Next.js) 팀 간의 인적 교류가 너무 커서, 버셀(Vercel)에게 선도적인 이점을 제공하고 있습니다

    리믹스(Remix)처럼 버셀(Vercel)이나 페이스북(Facebook) 생태계에 속하지 않는 다른 프레임워크(framework)들은, 리액트(React) 내부에서 이미 수정되었지만 아직 배포되지 않은 버그(bug)들 때문에 영향을 받을 수 있습니다

커뮤니티의 긍정적인 태도

커뮤니티 내에서 증가하는 반대 목소리에 직면하여, 리액트(React)의 주요 기여자 중 한 명인 댄 아브라모프(Dan Abramov) 역시 여러 차례 자신의 견해를 밝혔습니다

그는 기술 변화에 대해 열린 태도를 가지고 있습니다

  • 넥스트JS(Next.js)의 앱 라우터(App Router)는 매우 야심 찬 목표를 가지고 있지만, 아직 개발 초기 단계이며 앞으로 더욱 개선되고 훌륭해질 것입니다

  • 클라이언트 컴포넌트(Client Components)의 역할은 UI = f(state) 이고, 서버 컴포넌트(Server Components)의 역할은 UI = f(data) 입니다

    리액트(React)는 이 둘의 장점을 결합하여 UI = f(data, state) 를 달성하고자 합니다

    그는 커뮤니티가 이 목표 실현을 위해 함께 노력해 줄 것을 호소했습니다

  • 넥스트JS(Next.js)가 RSC를 운영 버전으로 출시한 것에 대해, 댄(Dan)은 "운영 환경 준비 완료(production-ready)"는 주관적인 판단이라고 생각합니다

    비록 RSC가 아직 카나리(canary) 버전이지만, 페이스북(Facebook) 내부에서는 이미 광범위하게 사용하고 있습니다

    그는 실제 사용 환경에서의 검증이 기술을 더 빠르게 개선하고 궁극적으로 성숙함과 안정성을 달성할 수 있다고 믿습니다

  • 새로운 기술의 발전은 지속적인 테스트, 피드백, 그리고 반복적인 개선을 포함하는 점진적인 과정입니다

    커뮤니티의 힘은 매우 중요합니다

전반적으로 댄(Dan)은 모든 사람이 편견을 잠시 접어두고, 실제 사용 경험을 통해 리액트(React)의 다음 단계 변화를 함께 탐구해 나가기를 희망하고 있습니다

결론적으로

RSC는 현대 웹 애플리케이션(application) 개발을 향상시키는 데 분명 긍정적인 의미를 가집니다

가장 명백한 장점은 대규모 애플리케이션(application)의 성능을 개선하고, 클라이언트(client) 측 부하를 줄이며, 데이터 가져오기 프로세스(process)를 최적화할 수 있다는 점 등입니다

이러한 작업들을 RSC를 통해 완료하는 것이 이전의 서버 사이드 렌더링(Server-Side Rendering, SSR) 솔루션(solution)들보다 더 편리할 수 있습니다

Node.js v20의 출시와 RSC의 적용으로, 프론트엔드(front-end)와 서버(server) 사이의 거리는 더욱 좁혀지고 있습니다

우리는 프론트엔드(front-end) 작업의 "백엔드화(backendization)"를 목격할 기회를 맞이하고 있습니다

즉, 프론트엔드(front-end) 엔지니어(engineer)들이 데이터 조회 최적화, 서버 자원 관리 등 전통적으로 백엔드(back-end) 영역에 속했던 더 많은 작업을 처리하게 될 것이라는 의미입니다

이는 사실 프론트엔드(front-end) 엔지니어(engineer)들에게 새로운 문을 열어주는 것이며, 웹 전체를 포괄적으로 마스터할 수 있는 기회를 제공합니다