본문으로 건너뛰기
← Development Log

Development Log

U+tv모바일 홈 성능 개선 및 App Router 마이그레이션.

기존 U+모아tv 홈의 초기 렌더링 병목을 개선하고, 차세대 U+tv모바일의 App Router·SSR·Hydration 구조로 이관한 과정을 정리한 사례입니다.

  • #Next.js
  • #Performance
  • #SSR
  • #TanStack Query

기존 U+모아tv 홈의 초기 렌더링 병목을 개선하고, 성능 개선 경험을 차세대 U+tv모바일의 Next.js App Router 구조로 이관한 프로젝트. 홈 데이터 로딩·이미지 우선순위·SSR/CSR 연계와 Hydration 경계를 함께 재설계했으며, 차세대 서비스 운영 환경에서 일별 p75 LCP 평균 약 1.45초를 확인했다.

프로젝트 개요

항목내용
서비스기존 **U+모아tv** 홈 성능 개선 → 차세대 **U+tv모바일** 홈 마이그레이션·고도화
수행 기간성능 개선·구조 이관 **2024.10\~2026.05** / 운영 지표 검증 **2026.05\~2026.08**
담당 역할프론트엔드 개발, 홈 SSR·데이터 로딩 구조 개선, App Router 이관, WebView 사용자 환경 대응, 운영 지표 분석
기술Next.js 12 → 16, React 18 → 19, TypeScript, TanStack Query v5, Zustand, IntersectionObserver, Datadog RUM

문제와 목표

기존 U+모아tv 홈은 MFA 기반 CSR 구조로, 브라우저에서 JavaScript 실행과 API 조회가 완료된 뒤 주요 콘텐츠가 노출됐다. 최상단 배너와 화면 밖 이미지까지 초기 요청에 포함되면서 LCP와 레이아웃 안정성이 저하됐고, 홈의 데이터 조회·렌더링 책임이 페이지와 전역 스토어에 결합돼 있었다. 차세대 U+tv모바일 이관에서는 단순한 프레임워크 업그레이드보다 다음 목표를 우선했다.

  • 첫 화면에 필요한 콘텐츠를 서버에서 먼저 제공
  • 초기 화면 밖의 데이터와 이미지 요청을 사용자 스크롤 시점까지 지연
  • SSR과 CSR에서 동일한 인증 정보와 Query Cache를 사용
  • 일부 패널 API 장애가 홈 전체 장애로 확대되지 않도록 격리

담당 업무 및 기술적 기여

1. CSR 중심 홈을 SSR·Hydration 구조로 전환

기존 Pages Router 홈에서 첫 화면에 필요한 패널 데이터를 서버에서 조회하고, TanStack Query의 Prefetch·Dehydrate·Hydration으로 클라이언트에 전달했다. 서버가 전달한 Query Cache를 브라우저에서 재사용하도록 구성해 초기 진입 시 동일 API가 다시 호출되거나 화면이 중복 렌더링되는 문제를 줄였다. 모든 패널을 서버에서 조회하면 응답 시간이 길어지는 점을 고려해, 첫 화면에 필요한 상단 패널만 선별적으로 SSR하고 나머지는 클라이언트에서 조회하도록 경계를 설계했다.

2. 이미지 로딩 병목 개선

Chrome Performance와 Lighthouse를 이용해 최상단 스와이퍼 이미지를 LCP 요소로 특정했다. 화면 밖 이미지는 지연 로딩하고, 첫 배너 이미지는 eager loading과 높은 요청 우선순위를 적용했다. 기존 서비스에서는 next/image 기반 크기·포맷 최적화를 적용했고, 차세대 서비스에서는 공통 ThumbImage에서 이미지 캐시 URL·lazy/eager·fetchPriority를 제어하도록 통합했다.

3. Next.js App Router 기반 차세대 홈으로 이관

Next.js 12 Pages Router의 getInitialProps 중심 구조를 Next.js 16 App Router의 async Server Component 구조로 전환했다.

  • 라우트 전용 layout.tsx로 Header·Footer·Navigation 책임 분리
  • Server Page에서 요청 쿠키와 서비스 설정을 읽고 홈 데이터를 Prefetch
  • HydrationBoundary를 통해 Server Page와 Client Page의 Query Cache 연결
  • app / views / widgets / entities / shared 계층으로 페이지·패널·API·공통 로직 분리 이를 통해 서버 전용 로직이 브라우저 영역에 섞이지 않도록 하고, 화면 구성과 데이터 조회의 변경 범위를 줄였다.

4. 선별 SSR과 뷰포트 기반 지연 조회

차세대 홈에서는 UTV_PANEL_LIMIT=5를 기준으로 상단 4개 패널의 스케줄·OTT·배너·이어보기 데이터를 SSR Prefetch했다. 이후 패널은 초기 쿼리를 비활성화하고, 각 패널이 뷰포트 400px 전까지 접근했을 때 IntersectionObserver가 개별 쿼리를 활성화하도록 구현했다. 기존의 “일정 위치에서 나머지 패널 전체 노출” 방식보다 데이터 요청 시점을 세분화해 초기 API 요청과 브라우저 렌더링 부담을 줄였다.

5. SSR·CSR 개인화 데이터 일관성 확보

서버 요청의 쿠키에서 sa_id·stb_mac·userKey를 추출해 개인화 패널 조회에 사용했다. 클라이언트 인증 스토어가 복원되기 전에는 서버에서 전달한 값을 사용하고, Hydration 이후에는 Zustand의 최신 값으로 전환했다. SSR과 CSR의 인증 컨텍스트 및 Query Key를 일치시켜 로그인 사용자 홈에서 발생할 수 있는 중복 조회·재렌더링·Hydration 불일치를 줄였다.

  • 초기 5회 평균, 최종 Lighthouse 리포트, 차세대 Datadog RUM은 측정 시점과 환경이 다르므로 하나의 연속 실험처럼 직접 연결하지 않았다.

성과

개발 환경 단계별 성능 개선

측정 방법과 수치의 범위

  • 기존 U+모아tv 홈의 개발·QA 환경에서 Chrome Lighthouse와 Performance Panel을 사용했다.
  • 초기 SSR 효과 검증은 동일 조건에서 기존 dev와 SSR 적용 dev-1을 각각 5회 측정해 평균을 비교했다.
  • 최종 34 → 84 지표는 MFA+CSR 기준 리포트와 SSR·이미지 최적화 적용 리포트를 비교한 별도 Lighthouse 측정이다.

1단계 — 선별 SSR 효과 검증

상단 4개 패널만 서버에서 Prefetch하고 나머지는 클라이언트에서 조회한 초기 실험에서 5회 평균 Performance는 32.2 → 49.2, LCP는 4.46초 → 3.20초, TBT는 392ms → 102ms로 변화했다. SSR·lazy loading 미적용 dev: 5회 평균 Performance 32.2, LCP 4.46초 선별 SSR·lazy loading 적용 dev-1: 5회 평균 Performance 49.2, LCP 3.20초 Source:

2단계 — SSR·이미지 로딩 최적화

SSR 적용만으로 LCP 병목이 완전히 해소되지 않아 화면 밖 이미지를 지연 로딩하고, next/image를 통해 크기·포맷·요청 우선순위를 조정했다.

지표기존 MFA + CSRSSR + 이미지 최적화변화
Lighthouse Performance34점84점**50점 상승**
FCP2.3초0.4초**약 82.6% 단축**
LCP12.2초2.7초**약 77.9% 단축**
Speed Index6.7초1.1초**약 83.6% 단축**
CLS0.690.002**약 99.7% 감소**

기존 MFA + CSR 기준 Lighthouse 리포트 SSR·next/image 적용 후 Lighthouse 최종 리포트

3단계 — LCP 요소 특정과 최상단 배너 우선 로딩

Lighthouse 진단에서 최상단 스와이퍼의 첫 배너를 LCP 요소로 특정했다. 해당 이미지의 로드 지연이 약 2,230ms로 전체 LCP 2.7초의 대부분을 차지해, 최상단 패널의 첫 이미지만 eager·high priority로 요청하고 나머지는 lazy loading을 유지했다. 원인 분석: LCP 구성 요소와 이미지 로드 지연 확인 추가 개선: 최상단 배너 우선 로딩 후 LCP 2.7초 → 1.3초 최초 측정값 12.2초 대비 최종 1.3초로 약 89.3% 단축했으며, 단계별 원본 기록과 구현 과정은 에서 확인할 수 있다.

보조 근거 — SSR·ISR·CSR 렌더링 구간 분석 별도의 Chrome Performance 실험에서는 HTML 다운로드·서버 렌더링, JavaScript 평가, FCP/LCP, Hydration 구간을 나눠 렌더링 방식별 병목을 확인했다. 아래 이미지는 SSR+CSR 환경의 단일 trace이며 Lighthouse·RUM 결과와 직접 비교하지 않는다. ![](https://prod-files-secure.s3.us-west-2.amazonaws.com/011efe02-e80e-4435-975e-c1d52e765464/c67f79f8-670e-4603-91e6-8505942b2f45/umoa-trace-ssr.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=ASIAZI2LB466SSKLAJOX%2F20260916%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20260916T081210Z&X-Amz-Expires=3600&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEEgaCXVzLXdlc3QtMiJGMEQCIGVmvptTRE9ILgR2snWn8Mwf9NhReBN03A%2BA9J2GEnQnAiAe1YRw9Q9nKB%2BR5VVgcWzYMdFIsinZAj69r8Wco8pe9ir%2FAwgREAAaDDYzNzQyMzE4MzgwNSIM31yEFEbow5Oy6vxaKtwD%2FMqsHl6rCeGIwSzR2f4fHZCGvrWA5aPmDuqoxR50%2FGersS43jEkgMmOudfxxuOlu6tG2KOO%2B0L9V8ASB8JDKFMJaTS2y3jW4SfbdT%2BBRAjXQSsRaAl6r%2BSkJEiYr3u8spdARcIdK3z%2BXeeXTzfHpy2M1mJPBx%2FgGwZpGSllmeG%2FRu1RFhflfVdHhvxv7MQmzPTFuTZ9CN%2F67%2BIkJo7wGjTn%2B3z4ky73wz0WNQcwO1GmNsH3krHLF8KSCCz6PrC5tyH7Cw8%2FC2ssOV5Q4pDVYTyTGteDOxTCHA24P%2FXTJ70kSpJlLh2loZ8adfD7zo22CqG%2B6eRzo6rEzuKIgoB%2FSrzpqWrjiIOWyxBHwSTjw0NVyUQrW61fWXaE0J%2BUUJixtN93fQxSwTp7GeBj9xlsoT17vosiB19%2B1zs7t6hzx1KvPAhZoH9SLLWBwht3MTlO3ksqjzREs3OMKD8yoF7oe01Ozg06ZJf5qsKhiYEbzCOlcCrKXeryREWH0rWR%2B3KNY6O5hu2K7q5O5R3dolQ%2F2kPR9aaiw8CQ9tpWNoap5AzgZLfyfWHPqSqwMvR6mju%2B5jnC3J52Wa8CUeIvLLQbCJEgapDdW0QbGKgtoHS7Y3sNmgHoart3ckfzNCKowqJWp1QY6pgH%2F6NNXw0b0SWUI%2FoWgGAikfqHVjJA4Y5%2F%2F2jNFtfnm22twnnMNSV0eJWV09DvP1MNbqQTI3BTukxZzfhK9ZbCJgt2qSaT63WMFLIvFEGu1SLsj2EzgfNlJNCBZ%2FUoLzLbTDgEqcnSsRtfQLfVXyensVU6hkP%2BAdvOkHqn4YR4Sdi%2F3QMaQF%2Bs0CyKgbZiuVwgoGcPaQjvVz7a7AhnuZ%2Bw5MkjpkwKO&X-Amz-Signature=005eb868a307fab96fba47905745a839f8b6b2b1297b56534a9cf0263d14bb16&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject) Source:
### 차세대 서비스 운영 지표
지표Datadog RUM 관측값
관측 규모약 **458만 뷰 · 366만 세션**
웹·앱 합산 일간 고유 사용자평균 약 **2.68만 명**, 최대 **3.415만 명**
일별 p75 LCP 기간 평균약 **1.45초**
일별 p75 LCP 범위약 **0.93\~2.29초**

Datadog RUM 일별 p75 LCP 추이 — 기간 평균 약 1.45초 Datadog RUM 웹·앱 합산 일간 고유 사용자 추이 — 평균 약 2.68만 명, 최대 3.415만 명

핵심 의사결정

의사결정판단 근거효과
전체 SSR 대신 상단 4개 패널만 Prefetch첫 화면 노출과 서버 응답 비용의 균형초기 콘텐츠는 서버에서 제공하고 불필요한 요청은 지연
Hydration 전후 인증값 전환서버 쿠키와 클라이언트 스토어의 복원 시점 차이개인화 데이터의 SSR·CSR 일관성 확보
패널별 IntersectionObserver 적용하단 전체 패널을 한 번에 조회하는 비용사용자가 접근하는 패널만 순차 조회
`Promise.allSettled` 적용일부 API 실패가 홈 전체에 미치는 영향 제한패널 단위 실패 격리와 홈 가용성 향상

결과 요약

  • 기존 MFA·CSR 홈을 SSR·TanStack Query Hydration 구조로 전환
  • Next.js 12 Pages Router에서 Next.js 16 App Router로 홈 구조 이관
  • 데이터·이미지 로딩 우선순위 조정으로 LCP 12.2초 → 1.3초
  • 차세대 운영 환경에서 일별 p75 LCP 평균 약 1.45초 확인
  • 458만 뷰·366만 세션, 일간 고유 사용자 평균 약 2.68만 명 규모에서 운영

측정 기준

  • Lighthouse 수치는 기존 U+모아tv 홈의 단계별 개선 과정에서 측정한 개발·QA 환경 결과다.
  • 초기 SSR 실험의 5회 평균과 최종 Lighthouse 리포트는 별도 측정이므로 동일 실험의 연속 수치로 해석하지 않는다.
  • Datadog RUM 수치는 차세대 U+tv모바일의 실제 웹·앱 사용자 환경을 1일 단위로 집계한 결과다.
  • RUM 평균은 초기 데이터 누적 구간과 마지막 집계 중인 당일 값을 제외한 그래프 기반 근사치다.
  • Lighthouse·Chrome Performance·Datadog RUM은 측정 환경과 목적이 다르므로 서로 직접적인 전후 비교값으로 사용하지 않았다.

Sources