SSR과 템플릿 엔진 선택 기준
SSR의 가치, 템플릿 엔진 비교, XSS 안전한 데이터 주입 원칙을 다룬다
Posted
By okorion
SSR과 템플릿 엔진 선택 기준
결론 요약
- SSR(Server-Side Rendering)은 “과거 기술”이 아니라 초기 응답·SEO·폼 UX를 안정적으로 해결하는 설계 선택지다.
- 템플릿 엔진은 HTML 생성 도구가 아니라 반복·조건·레이아웃을 서버에서 관리하기 위한 제어 장치다.
- Pug/EJS/Handlebars의 차이는 문법 취향이 아니라 디버깅·협업·유지보수 비용에서 갈린다.
- 데이터 주입은 편의보다 XSS 최소화 규칙을 먼저 잡아야 한다.
- 오늘날 SSR은 관리자/백오피스/콘텐츠 중심 페이지에서 강하고, 고상호작용 SPA에는 부적합하다.
서버 사이드 렌더링(SSR)과 템플릿 엔진 선택 기준
1️⃣ 정의: SSR이란 무엇인가 (Client Rendering과 비교)
SSR(Server-Side Rendering)
- 서버가 HTML을 완성해서 클라이언트에 전달
- 브라우저는 받은 HTML을 즉시 렌더링
CSR(Client-Side Rendering)
- 서버는 JSON만 제공
- 브라우저에서 JS가 HTML을 생성
| 구분 | SSR | CSR |
|---|---|---|
| 최초 화면 | 빠르고 안정적 | JS 로딩 후 렌더 |
| SEO | 유리 | 불리(추가 작업 필요) |
| 폼/에러 UX | 단순 | 복잡 |
| 상호작용 | 제한적 | 강함 |
| 복잡도 | 서버 집중 | 프론트 집중 |
왜 지금도 배우는가 SSR은 “프론트 대체”가 아니라 서버 중심 화면 생성이 더 합리적인 영역을 정확히 커버한다.
2️⃣ 왜 필요한가: 순수 HTML을 관리하면 생기는 문제
순수 HTML 파일로 서버 렌더링을 하면 다음 문제가 즉시 발생한다.
- 반복되는 마크업(리스트)
- 조건부 렌더링(로그인/비로그인)
- 공통 레이아웃(헤더/푸터)
- 폼 검증 실패 시 입력값 유지
템플릿 엔진은 이 문제를 서버 단에서 선언적으로 해결한다.
3️⃣ 어떻게 동작하는가: 템플릿 엔진의 역할
템플릿 엔진은 다음을 제공한다.
- 반복(loop): 리스트 렌더링
- 조건(condition): 상태별 출력
- 레이아웃(layout): 공통 구조 재사용
- partial/include: 컴포넌트화
핵심: HTML을 “문자열”이 아니라 데이터 바인딩 결과물로 취급한다.
4️⃣ toy 예시: 상품 리스트 렌더링
데이터
1
2
3
res.render('products', {
products: [{ name: 'A' }, { name: 'B' }]
});
EJS 예시
<ul>
<% products.forEach(p => { %>
<li><%= p.name %></li>
<% }) %>
</ul>
- 반복/출력 분리
- 데이터 없을 경우 조건 처리 가능
5️⃣ 실무 예시: 폼 검증 오류 + 입력값 유지
문제
- 검증 실패 시 입력값이 사라짐
- 사용자 재입력 비용 증가
해결 패턴(SSR)
1
2
3
4
res.render('form', {
error: '가격은 숫자여야 합니다',
oldInput: req.body
});
<input name="price" value="<%= oldInput.price %>" />
<% if (error) { %>
<p><%= error %></p>
<% } %>
이 UX는 CSR에서도 가능하지만, SSR에서는 추가 상태 관리 없이 자연스럽다.
6️⃣ Pug vs EJS vs Handlebars 비교
| 항목 | Pug | EJS | Handlebars |
|---|---|---|---|
| 문법 | 들여쓰기 기반 | HTML + JS | HTML + 제한된 표현식 |
| 생산성 | 빠름(익숙하면) | 보통 | 보통 |
| 디버깅 | 어려움(라인 추적) | 쉬움 | 중간 |
| 협업 | 디자이너 불리 | 유리 | 유리 |
| 유지보수 | 취향 의존 | 안정적 | 구조 강제 |
| 로직 허용 | 높음 | 높음 | 낮음(의도적) |
선택 기준 요약
- Pug: 소규모/개인 프로젝트, 빠른 작성
- EJS: 학습·디버깅·유지보수 균형
- Handlebars: 로직 제한을 통한 구조 강제(팀 협업)
7️⃣ 데이터 주입과 XSS 최소 규칙
핵심 원칙 3가지
- 출력 시 escape가 기본인지 확인
- 사용자 입력은 그대로 HTML로 넣지 않는다
innerHTML유사 동작은 피한다
- EJS:
<%= %>는 escape,<%- %>는 raw - raw 출력은 신뢰된 데이터에만 사용
과도한 보안 설명은 필요 없다. “raw 출력은 최후의 수단”만 기억하면 된다.
8️⃣ 오늘날 실무 결론: 어디에 쓰면 좋은가 / 나쁜가
쓰면 좋은 경우
- 관리자/백오피스
- CMS, 블로그, 문서 페이지
- 폼 중심 서비스
- SEO가 중요한 랜딩
쓰면 나쁜 경우
- 실시간 상호작용이 많은 앱
- 상태 전이가 복잡한 SPA
- 클라이언트 로직이 중심인 서비스
SSR은 “대체재”가 아니라 역할이 명확한 선택지다.
재학습 포인트 체크리스트
- SSR과 CSR의 차이를 UX 기준으로 설명할 수 있다
- 템플릿 엔진이 해결하는 문제 4가지를 말할 수 있다
- Pug/EJS/Handlebars의 트레이드오프를 안다
- 폼 검증 실패 UX를 SSR로 구현할 수 있다
- raw 출력과 escape 출력의 차이를 이해한다
- SSR이 적합한 서비스 유형을 구분할 수 있다
This post is licensed under CC BY 4.0 by the author.
