피드로 돌아가기
올리브영 테크블로그Frontend
원문 읽기
Front-end 개발자가 회고하는 기획전 개편
올리브영이 JSP 기반 기획전 시스템을 Next.js로 마이그레이션하며 dangerouslySetInnerHtml과 createRoot를 조합해 동적 HTML 내부에 React 컴포넌트 삽입
AI 요약
Context
Back-office 에디터에서 생성한 사용자 정의 HTML을 기획전 상세 페이지에서 렌더링해야 했으나, HTML 문자열 내부에 기존 Next.js 상품 카드 컴포넌트를 삽입해야 하는 아키텍처 문제가 발생했습니다.
Technical Solution
- HTML 모듈을 dangerouslySetInnerHtml로 DOM에 주입: BO에서 생성된 신뢰할 수 있는 데이터로 판단하여 dompurify 없이 직접 삽입
- createRoot API를 사용한 다중 root 생성: useEffect에서 DOM 렌더링 후 특정 클래스 요소를 기준으로 React 컴포넌트를 삽입
- 다중 root 환경에서 RecoilRoot와 QueryClientProvider로 감싸기: 각 createRoot마다 전역 상태관리(Recoil)와 서버 통신(react-query)을 독립적으로 구성
- iOS lazy load 비활성화: 동적 이미지 크기로 인한 위치 계산 오류를 방지하기 위해 iOS 환경에서 lazy load 미적용
- window.scrollTo를 통한 스크롤 위치 계산: ref 기반 scrollIntoView 대신 수동 위치 계산으로 다른 컴포넌트 스크롤 이벤트 충돌 회피
Impact
React.Profiler를 통한 성능 분석 결과 createRoot로 생성된 컴포넌트의 변경이 기존 컴포넌트에 지장을 주지 않음을 확인하였습니다.
Key Takeaway
다중 root 환경에서도 Virtual DOM diffing 횟수가 증가하지 않으므로 성능 저하를 우려할 필요가 없으며, 주어진 기간 내 완전한 기능 구현이 선행 최적화보다 중요한 프로덕트 개발 원칙입니다.
실천 포인트
Next.js 또는 React 기반 서비스에서 dangerouslySetInnerHtml로 외부 HTML을 렌더링할 때, createRoot를 활용해 특정 DOM 노드에 기존 컴포넌트를 삽입할 수 있으며, 이때 RecoilRoot/QueryClientProvider를 각 root마다 래핑하면 상태관리와 비동기 통신이 정상 작동합니다.