1. 나의 선택: SSR 기반의 하이브리드 아키텍처 (The Best of Both Worlds)
1부에서 SSR(타임리프)과 CSR(리액트 등)의 장단점을 분석한 결과, 나는 **'가상 주식 거래소'**라는 프로젝트의 특성에 맞춰 두 가지 방식을 혼합하기로 결정했다.
(1) 왜 하이브리드인가?
- SSR의 필요성: 로그인/회원가입, 내 자산 현황 등은 **보안(Security)**이 중요하고, 초기 접속 시 완성된 화면을 보여주는 것이 사용자 경험에 좋다. (SEO 및 초기 로딩 속도 이점)
- CSR(Fetch)의 필요성: 주식 시장은 1초마다 가격이 변한다. 가격이 변할 때마다 페이지 전체를 새로고침(F5)하는 SSR 방식은 사용자 눈에 피로감을 주고 트래픽 낭비가 심하다.
(2) 구현 전략
- 뼈대 (Skeleton) -> SSR: 헤더, 푸터, 메뉴, 그리고 기본적인 사용자 정보는 Thymeleaf를 통해 서버에서 완성된 HTML로 내려준다.
- 알맹이 (Real-time Data) -> CSR (Fetch): 주식 현재가, 매수/매도 후 잔고 갱신 등 실시간성이 필요한 데이터만 자바스크립트의 fetch API를 통해 JSON으로 받아와 화면 일부분만 업데이트(DOM 조작)한다.
2. 오해와 진실: "타임리프 안의 fetch는 누가 실행하는가?"
구현 과정에서 가장 혼란스러웠던 점은 코드의 실행 위치였다.
"이 자바스크립트 코드는 분명 백엔드 프로젝트의 src/main/resources/templates 폴더 안에 적혀 있다. 그럼 서버가 이 코드를 실행해서 데이터를 가져오는 건가?"
이것은 **'파일의 저장 위치'**와 **'코드의 실행 위치'**를 혼동한 데서 온 오해였다.
- Server (Spring Boot): templates에 있는 HTML 파일을 읽는다. 이때 <script> fetch(...) </script> 부분은 그저 단순한 텍스트 문자열로 취급하여 클라이언트에게 전송('배달')한다.
- Network: HTML 문서가 인터넷을 타고 브라우저로 이동한다.
- Client (Browser): 브라우저가 HTML을 해석하다가 <script> 태그를 만나는 순간, 내장된 자바스크립트 엔진(V8 등)을 통해 코드를 실행한다.
결론: templates 폴더에 있더라도, fetch 함수를 호출하여 서버에 "데이터 줘!"라고 요청하는 주체는 백엔드가 아닌 **사용자의 브라우저(클라이언트)**다.
3. 성능 심화 1: CSR은 매번 무거운 JS를 다운로드할까? (Cache)
CSR 방식(혹은 내가 쓴 하이브리드 방식)은 화면을 그리기 위해 자바스크립트 파일이 필수적이다. 그렇다면 페이지를 옮길 때마다 JS 파일을 다운로드하느라 느려지지 않을까?
여기서 웹의 핵심 기술인 **브라우저 캐시(Browser Cache)**가 등장한다.
- 첫 번째 방문 (Cold Start): HTML과 연결된 JS, CSS 파일을 서버로부터 다운로드한다. (예: 200ms 소요)
- 두 번째 방문 (Warm Start): 브라우저는 "어? 이 파일 아까 받았던 건데?"라고 인식하고, 서버에 요청을 보내지 않고 **내부 저장소(Memory/Disk Cache)**에서 파일을 꺼내 쓴다. (예: 0ms 소요)
따라서, 초기에 JS 파일 용량이 조금 크더라도, 두 번째 접속부터는 SSR 못지않은 빠른 속도를 낼 수 있다.
4. 성능 심화 2: 누가 땀을 흘리는가? (CPU Resource)
마지막으로, **"렌더링 방식에 따라 하드웨어 자원을 누가 더 많이 쓰는가?"**에 대한 의문을 정리했다. 이는 서비스 규모가 커졌을 때 비용 문제와 직결된다.
(1) SSR (Server Side Rendering)
- 주요 부하: Server CPU
- 설명: 사용자 1명이 접속할 때마다 서버가 HTML 문자열을 조립하고 연산해야 한다.
- 장단점: 클라이언트(사용자)의 폰이 구형이어도 화면이 잘 뜬다. 하지만 사용자가 10만 명으로 늘어나면 **서버 비용(AWS)**이 급격히 증가한다.
(2) CSR (Client Side Rendering)
- 주요 부하: Client CPU
- 설명: 서버는 정적 파일만 던져주고 쉰다. 사용자의 브라우저가 JS를 해석하고 화면을 그리는 무거운 작업을 도맡아 한다.
- 장단점: 서버 비용을 획기적으로 줄일 수 있다. 하지만 사용자의 기기 성능이 낮다면(저사양 스마트폰) 화면이 버벅거리거나 배터리가 빨리 닳는다.
(3) 나의 프로젝트 (Hybrid)
- 나는 이 둘의 균형을 맞췄다.
- 기본적인 페이지 구성은 서버가 담당하여 초기 로딩 안정성을 확보하고,
- 빈번한 데이터 갱신은 클라이언트에게 위임하여 서버의 불필요한 재렌더링 부하를 줄였다.
5. 마무리: 개발자의 시야
이번 탐구를 통해 단순히 "로그인 페이지를 어디에 만들까?"라는 질문이 웹의 동작 원리, 네트워크 캐싱, 그리고 컴퓨팅 자원의 효율적 분배라는 거대한 아키텍처 설계의 영역으로 확장되는 것을 경험했다.
백엔드 개발자라고 해서 단순히 API만 만드는 것이 아니라, 클라이언트가 데이터를 어떻게 받아오고 브라우저가 어떻게 렌더링하는지를 이해해야만 최적의 사용자 경험을 주는 서비스를 설계할 수 있다는 점을 배웠다.
'개발 공부 > 백엔드' 카테고리의 다른 글
| [Spring Boot] 웹 아키텍처 설계의 여정 (3): 주소창에 URL을 치면 일어나는 일 (Network & Controller) (0) | 2026.01.09 |
|---|---|
| [Spring Boot] 웹 아키텍처 설계의 여정 (1): 폴더 구조부터 WAS의 동작 원리까지 (0) | 2026.01.09 |
| 백엔드 개발자를 위한 '생존형' 자바스크립트 (Fetch API & Debugging) (0) | 2026.01.03 |
| 제미나이와 게시판 만들기: (8) Docker로 배포 준비하기 🐳 (0) | 2025.10.11 |
| 제미나이와 게시판 만들기: (7) 인가(Authorization) 적용과 API 문서화 (0) | 2025.10.08 |