새로운 프로젝트의 시작을 알린 회의 이후, React Core Team의 논의는 한층 더 깊어졌다. 화이트보드는 온갖 아이디어와 다이어그램으로 가득 찼다가 지워지기를 반복했다. 그들은 세바스찬이 던진 ‘무대 뒤의 배우’라는 개념을 구체화하기 위해 애썼다.
“서버에서 더 많은 렌더링을 처리하는 건, 결국 더 발전된 형태의 SSR일 뿐이지 않나?”
한 엔지니어가 의문을 제기했다. 타당한 지적이었다. 서버에서 HTML을 생성하는 것은 이미 수십 년 된 기술이었다. React가 여기서 무엇을 더 할 수 있단 말인가.
“핵심은 ‘언제’ 렌더링하느냐가 아니라, ‘무엇을’ 클라이언트로 보내느냐에 있습니다.” 앤드류가 대화의 방향을 잡았다. “지금까지는 컴포넌트의 코드 자체를 클라이언트로 보내고, 클라이언트가 그 코드를 실행해 UI를 그렸습니다. 이 전제를 바꿔야 합니다.”
논의는 맴돌았다. 서버에서 실행되는 컴포넌트는 어떤 모습이어야 하는가? 클라이언트 컴포넌트와는 어떻게 다른가? 만약 상태(useState
)나 생명주기(useEffect
)를 가질 수 없다면, 그것을 과연 React 컴포넌트라고 부를 수 있을까? 팀원들은 각자가 가진 React에 대한 멘탈 모델의 한계 속에서 길을 잃어가고 있었다.
그때, 토론을 조용히 지켜보던 세바스찬 마크바게가 자리에서 일어났다. 그는 복잡한 다이어그램이 가득한 화이트보드를 깨끗이 지웠다. 팀원들의 시선이 그의 손끝에 모였다.
그는 아무것도 그리지 않았다. 대신, 모두를 향해 돌아섰다.
“우리가 너무 복잡하게 생각하고 있는 것 같군.”
그의 목소리는 조용했지만, 방 안의 모든 소음을 잠재웠다.
“SSR, 하이드레이션, 번들링… 이 모든 기술적인 용어들은 잠시 잊어버리자고. 그리고 가장 근본적인 질문으로 돌아가 보는 거야.”
세바스찬은 잠시 숨을 골랐다. 그의 눈빛은 마치 진리를 탐구하는 철학자와도 같았다.
“컴포넌트의 본질은 무엇이지? 입력을 받아 UI를 출력하는 함수. 그 이상도 이하도 아니야.”
그는 당연한 사실을 환기시켰다. 그리고 마침내, React의 역사를 바꿀 도발적인 질문을 던졌다.
“만약… 컴포넌트가 애초에 브라우저로 전송되지 않는다면?”
회의실에 정적이 흘렀다.
너무나 단순해서, 오히려 충격적인 질문이었다. 모두가 ‘어떻게 하면 코드를 더 잘 보내고, 더 잘 실행할까’를 고민할 때, 그는 ‘보내지 않는다’는 선택지를 꺼내 들었다.
질문의 의미를 곱씹던 팀원들의 얼굴에 서서히 변화가 나타났다.
컴포넌트의 자바스크립트 코드가 브라우저로 가지 않는다면?
당연히 번들 사이즈는 늘어나지 않는다.
자바스크립트가 없으니, 하이드레이션도 필요 없다.
서버에서 실행되니, 데이터베이스에 직접 접근해 네트워크 폭포수 없이 데이터를 가져올 수도 있다.
그동안 그들을 괴롭혔던 모든 문제들이, 세바스찬의 이 질문 하나로 한순간에 해결될 가능성을 내포하고 있었다.
이것은 SSR의 개선이 아니었다. 이것은 완전히 새로운 종류의 컴포넌트, 새로운 패러다임의 등장을 예고하는 신호탄이었다.
아직 이름도, 구체적인 형태도 없었다. 하지만 그 순간, 회의실에 모인 모두는 직감했다. 자신들이 웹 개발의 새로운 지평을 열 거대한 문 앞에 서 있다는 것을. React Server Components의 첫 씨앗이, 바로 그 정적 속에서 조용히 뿌려지고 있었다.