React · 2026-02-15

React SSR 캐싱 전략으로 서버 응답 속도 개선

React 기반 서버 사이드 렌더링 환경에서 HTML·데이터·엣지 캐시 계층을 설계하고 무효화·유지성을 다루는 캐싱 전략

작성일 : 2026-02-15 ㆍ 작성자 : 관리자
post
목차

개요

서버 사이드 렌더링(SSR)은 초기 로드 성능과 SEO에서 강점이 있다. 하지만 매 요청마다 렌더링 비용이 발생하면 응답 지연이 커진다. 그래서 캐시는 SSR 성능 개선의 핵심 수단이다. 이 글에서는 react ssr 캐싱 전략을 중심으로 ssr 성능 최적화와 서버 사이드 렌더링 캐시 설계 방법을 실무적으로 정리한다.

캐싱이 필요한 이유

응답 지연 감소

동일한 HTML을 여러 사용자에게 전달할 때 렌더 결과를 재사용하면 CPU와 렌더 시간 비용을 절감할 수 있다.

트래픽 부담 완화

빈번한 렌더링 요청을 캐시로 흡수하면 백엔드 API와 DB 호출을 줄인다.

캐싱 계층과 역할

효과적인 ssr 성능 최적화는 여러 계층을 적절히 결합하는 것이다. 우선순위는 CDN(엣지) → 서버 HTML 캐시 → 데이터(API) 캐시 → 컴포넌트 부분 캐시 → 브라우저 캐시 순으로 고려한다.

1) CDN / 엣지 캐시

가장 빠른 응답 개선 수단이다. 정적 HTML을 엣지에 둬서 지리적으로 가까운 노드에서 제공한다. s-maxage와 stale-while-revalidate 같은 지시자를 활용해 엣지에서의 재검증 정책을 정의한다.

2) 서버 HTML 캐시

동적 경로라도 캐싱 가능한 경우가 많다. LRU 같은 메모리 캐시, Redis 같은 외부 캐시를 사용해 완성된 HTML을 저장한다. 키는 요청 경로와 인증 상태 같은 변수를 반영한다.

3) 데이터(API) 캐시

SSR은 렌더링 전 데이터를 가져온다. 데이터 응답을 캐시하면 렌더 비용 자체는 남아있더라도 DB 호출을 줄여 전체 시간을 단축할 수 있다. TTL과 무효화 전략 설계가 중요하다.

4) 컴포넌트/부분 렌더 캐시

페이지 일부만 자주 변경되는 경우, 해당 부분의 HTML이나 직렬화된 상태를 캐시하면 효율적이다. React에서 부분 캐시를 적용할 때는 키 설계와 하위 상태 관리를 신중히 한다.

5) 브라우저 캐시

정적 자산과 가능하면 HTML에 대해 적절한 Cache-Control을 설정해 브라우저 레벨 캐시 활용을 유도한다.

무효화와 일관성

캐시 무효화는 도입보다 어렵다. 변경 시점에 따라 다음 전략을 조합한다.

  • 짧은 TTL: 자주 바뀌는 데이터에 적합
  • 이벤트 기반 무효화: 콘텐츠 변경 시 키를 삭제
  • 서로게이트 키(Surrogate Key): 관련 리소스를 그룹 단위로 무효화
  • stale-while-revalidate: 오래된 응답을 잠깐 제공하며 백그라운드 갱신

우선 적용 순서

  • 핵심 페이지 먼저: 트래픽이 높은 페이지만 우선 캐시
  • 데이터 캐시 병행: 렌더 비용과 데이터 비용 둘 다 고려
  • 모니터링으로 보정: 캐시 적중률과 응답시간을 지표로 조정

구현 예시

아래 예시는 Express 서버에서 LRU 메모리 캐시로 SSR HTML을 저장하는 단순한 패턴이다.

const LRU = require('lru-cache')
const cache = new LRU({ max: 1000, maxAge: 1000 * 60 })
app.get('*', async (req, res) => {
  const key = req.originalUrl
  const cached = cache.get(key)
  if (cached) {
    res.setHeader('X-Cache', 'HIT')
    return res.send(cached)
  }
  // 서버 렌더링 수행
  const html = await renderToString(<App />)
  cache.set(key, html)
  res.setHeader('X-Cache', 'MISS')
  res.send(html)
})

데이터 계층을 Redis에 캐시하는 예시는 다음과 같다.

const redis = require('./redisClient')
async function fetchData(key, fetcher, ttl = 60) {
  const cached = await redis.get(key)
  if (cached) return JSON.parse(cached)
  const data = await fetcher()
  await redis.setEx(key, ttl, JSON.stringify(data))
  return data
}
// SSR에서 fetchData를 사용해 API 호출을 줄인다.

CDN과 협업할 때 권장되는 HTTP 헤더 예시:

// 엣지에서 짧게 캐시하고 백그라운드 갱신 허용
res.setHeader('Cache-Control', 'public, max-age=0, s-maxage=60, stale-while-revalidate=30')
// 특정 경로는 장기 캐시
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable')

성능 측정과 모니터링

적중률(Hit Rate), TTFB(첫 바이트 응답 시간), 전체 응답 시간, CPU 사용률을 지속적으로 관찰한다. 로드 테스트로 캐시 도입 전후를 비교한다. 모니터링 결과로 TTL과 계층 조합을 조정한다.

실무 팁 요약

  • 핵심 페이지부터 단계적으로 캐시 적용
  • 무효화 정책을 코드화해서 일관성 유지
  • 데이터와 HTML 캐시를 분리해 복원성 확보
  • stale-while-revalidate로 사용자 경험과 최신성 균형
  • CDN과 서버 캐시를 함께 설계해 최단 경로 응답 확보

결론

react ssr 캐싱 전략은 여러 계층을 조합해 성능을 극대화하는 작업이다. 단일 기술로 해결하기보다 CDN, 서버 HTML, 데이터 캐시를 목적에 맞게 설계하면 ssr 성능 최적화에 실질적 이득을 얻는다. 적용 후에는 측정과 조정을 통해 지속적으로 개선하는 것이 중요하다.

react ssr 캐싱 전략 ssr 성능 최적화 서버 사이드 렌더링 캐시 SSR 캐시 CDN 캐싱 Redis 캐시 Cache-Control stale-while-revalidate