세바스찬의 질문은 팀의 사고방식을 완전히 뒤집어 놓았다. ‘보내지 않는다’는 발상은 단순한 아이디어를 넘어, 그들이 추구해야 할 새로운 북극성이 되었다. 그 북극성을 따라가다 보니, 꿈에 그리던 이상향이 눈앞에 펼쳐졌다.
“제로 번들 사이즈(Zero-Bundle-Size) 컴포넌트.”
다음 회의에서, 로렌 탄은 화이트보드에 이 다섯 단어를 적었다. 이제 그들의 목표는 명확했다.
“생각해보세요.” 그녀가 팀원들을 향해 열정적으로 설명하기 시작했다. “블로그 게시물 컴포넌트가 있다고 가정하죠. 이 컴포넌트는 제목, 본문, 작성자 정보를 데이터베이스에서 읽어와서 화면에 보여주기만 합니다. 사용자가 클릭하거나, 입력하거나, 상태가 바뀔 일이 전혀 없어요. 순수하게 정적인 콘텐츠죠.”
그녀는 말을 이어갔다. “지금까지 우리는 이 정적인 컴포넌트를 렌더링하기 위한 자바스크립트 코드까지 전부 클라이언트로 보냈습니다. 하지만 만약 이 컴포넌트가 서버에서만 실행된다면 어떻게 될까요?”
팀원들의 머릿속에서 시뮬레이션이 돌아가기 시작했다.
- 실행 환경: 서버.
- 역할: 데이터베이스에서 게시물 데이터를 직접 조회한다. API를 호출할 필요조차 없다.
- 렌더링: 조회한 데이터를 바탕으로 HTML 구조를 생성한다.
- 전송: 최종 결과물인 HTML만 클라이언트로 전송한다. 이 컴포넌트를 렌더링하는 데 사용된 자바스크립트 코드는 단 한 줄도 클라이언트로 가지 않는다.
결과는 놀라웠다. 클라이언트 입장에서 이 컴포넌트의 자바스크립트 비용은 ‘0’이었다. 번들에 포함되지 않으니 번들 사이즈에 영향을 주지 않고, 자바스크립트가 없으니 파싱하거나 실행할 필요도 없었다. 하이드레이션 과정에서도 그냥 건너뛰면 그만이었다.
“이것 봐.” 조쉬 스토리가 흥분된 목소리로 노트북 화면을 가리켰다. “수많은 의존성을 가진 마크다운 렌더링 라이브러리, 코드 하이라이팅 라이브러리… 이런 무거운 녀석들도 전부 서버에서만 처리하고 결과물만 보내면 되는 겁니다. 클라이언트는 아무 부담이 없어요.”
그의 말에 모두가 무릎을 쳤다. 그동안 번들 사이즈를 줄이기 위해 더 가벼운 라이브러리를 찾아 헤맸던 날들이 주마등처럼 스쳐 지나갔다. 하지만 이제는 그럴 필요가 없었다. 서버의 강력한 성능을 마음껏 활용해 무거운 작업을 처리하고, 클라이언트에는 그 결과만 가볍게 전달하면 되는 것이다.
‘제로 번들 사이즈’라는 꿈.
그것은 단순히 성능 최적화를 넘어, 웹 개발의 근본적인 비용 구조를 바꾸는 혁명이었다. 개발자는 더 이상 라이브러리 하나의 크기에 전전긍긍하지 않아도 됐다. 사용자는 의미 없는 코드 덩어리를 다운로드하느라 시간을 낭비하지 않아도 됐다.
물론 모든 컴포넌트가 제로 번들 사이즈가 될 수는 없었다. 사용자의 클릭에 반응하는 버튼, 입력에 따라 결과가 바뀌는 검색창처럼 상태와 상호작용이 필요한 컴포넌트는 여전히 클라이언트에서 실행되어야만 했다.
“그렇다면 우리에게는 두 종류의 컴포넌트가 필요하겠군요.”
앤드류가 논의를 정리했다.
“서버에서만 존재하는 컴포넌트. 그리고 기존처럼 클라이언트에서 실행되는 컴포넌트.”
그 꿈같은 개념에 ‘서버 컴포넌트(Server Components)’라는 이름이 잠정적으로 붙었다. 이제 남은 과제는 이 두 종류의 컴포넌트가 어떻게 서로를 인식하고, 데이터를 주고받으며, 하나의 애플리케이션 안에서 조화롭게 공존할 수 있는지에 대한 구체적인 방법을 설계하는 것이었다.
그들은 이제 막 새로운 대륙의 해안에 첫발을 내디뎠을 뿐이었다. 하지만 그 대륙에 무엇이 있을지 상상하는 것만으로도 팀원들의 심장은 뜨겁게 타오르고 있었다.