Server Components 2년 써보고 느낀 점
React Server Components를 실무에서 2년간 사용한 솔직한 회고
2024년 1월, "이게 뭐지?"
Next.js 14 프로젝트에서 처음으로 Server Components를 본격적으로 썼다. 첫 느낌은 솔직히 혼란이었다. 컴포넌트에 async를 붙이고, fetch를 그냥 호출하고, 근데 useState는 못 쓰고. 머릿속에서 기존 React 멘탈 모델이랑 계속 충돌했다.
2년 지난 지금, Server Components 없이 어떻게 개발했는지 오히려 기억이 안 난다.
제일 좋은 점: API 파일이 사라졌다
예전에는 프론트에서 데이터 가져오려면 API 엔드포인트 만들고, fetch하고, 로딩 상태 관리하고, 에러 처리하고. 이 루틴이 있었다. Server Components에서는 컴포넌트 안에서 직접 DB나 외부 API를 호출한다.
내 블로그 포스트 목록 페이지를 예로 들면, 이전에는 /api/posts 엔드포인트 만들고 클라이언트에서 useEffect로 호출했다. 지금은 page.tsx에서 getPosts() 직접 호출하면 끝. API 파일도 없고, 로딩 상태 관리도 없고, 코드가 절반으로 줄었다. 진짜.
2년 지나도 가끔 헷갈리는 부분
"이 컴포넌트는 서버인가 클라이언트인가?" 이 판단이 2년이 지나도 가끔 헷갈린다. 규칙은 단순하다. 인터랙션 없으면 서버, 있으면 클라이언트. 근데 실무에서는 "여기에 나중에 인터랙션이 추가될까?"라는 예측이 필요하고, 이게 종종 틀린다.
서버 컴포넌트로 짰다가 "여기에 좋아요 버튼 추가해주세요"가 오면, 컴포넌트를 클라이언트로 바꾸거나 버튼만 별도로 분리해야 한다. Server Components의 어려움은 기술이 아니라 설계다. 어디에 경계를 긋느냐의 감각이 필요하다. (이 감각은 아직도 발전 중이다.)
성능은 확실히 좋다
클라이언트로 보내는 JS 양이 줄어든 건 숫자로 나온다. 서버 컴포넌트로 전환한 프로젝트에서 초기 JS 번들이 체감상 3할 정도 줄었다. 내 블로그 기준으로 TTFB가 200ms쯤 빨라졌다. 서버에서 HTML 완성해서 보내니까 당연한 결과다.
디버깅은 2년이 지나도 불만이다
서버 컴포넌트에서 에러 나면 브라우저 콘솔이 아니라 서버 로그를 봐야 한다. 개발 중에는 터미널 같이 보면 되는데, 프로덕션에서는 로그 서비스 연결해야 한다. 특히 서버-클라이언트 경계에서 생기는 직렬화 에러가 까다롭다. Date 객체 넘기면 문자열 되고, Map이나 Set은 전달이 안 된다. 이런 에러가 빌드 타임이 아니라 런타임에 터지는 게 짜증난다.
새 팀원 적응 기간
새로 합류하는 사람이 Server Components에 적응하는 데 2~3주 걸린다. 기존 React 경험이 오히려 방해될 때도 있다. "컴포넌트는 브라우저에서 실행되는 거 아닌가요?"부터 시작해서 "그럼 useEffect는 언제 쓰나요?"까지. 한번 이해하면 오히려 더 단순한 모델인데, 기존 멘탈 모델을 부수고 다시 세우는 과정이 쉽지 않다.
어쨌든 방향은 맞다
Server Components는 웹 개발의 방향이 맞다고 확신한다. 서버에서 할 수 있는 걸 클라이언트로 안 보낸다는 원칙은 성능이랑 보안 양쪽에서 합리적이다. 근데 모든 프로젝트에 필요한 건 아니다. 인터랙션 많은 대시보드 같은 건 대부분 클라이언트 컴포넌트가 될 텐데, 그러면 이점이 제한적이다.
나처럼 콘텐츠 중심 사이트면 완벽한 선택이다. 실시간 협업 도구라면 경계 관리 비용이 이점을 상쇄할 수 있다. 도구는 맥락에 맞게 써야 한다. 당연한 말인데, 이 당연한 걸 잊기 쉽다.