DERMA:CODE
데이터 과부하를 Hexa 시각 모델로 해결하고, LCP 66% 개선으로 상담 흐름을 개선한 AI SaaS
클리닉 상담 현장에서 사용하는 얼굴 촬영 기반 AI 피부 분석 SaaS로, 피부 상태를 정량화하고 맞춤 시술·제품 추천을 제공합니다. 분석 결과가 실제 시술 결정으로 이어지도록 상담 흐름 전반의 사용자 경험을 설계했습니다.
The Challenge
타 AI 피부 분석 장치는 방대한 데이터를 제공하지만, 환자가 이를 자신의 피부 상태와 연결해 실질적인 인사이트로 이해하기에는 여전히 간극이 존재했습니다. 복잡한 분석 결과를 직관적으로 해석 가능하게 만들고, 상담에서 시술 결정까지 자연스럽게 이어지는 경험 설계가 필요했습니다.
- 데이터 과부하와 낮은 해석 가능성: AI 분석 결과가 텍스트와 수치 중심으로 제공되어 상담사가 제한된 시간 내 핵심 지표를 효과적으로 전달하기 어려웠습니다.
- 단절된 사용자 여정: 분석 결과를 확인한 후 다음 행동(시술 결정)으로 자연스럽게 유도하는 UX 장치가 부족하여 실제 시술로 이어지지 않는 이탈률이 발생했습니다.
- 제품의 시각적 차별성 부족: DERMA:CODE의 핵심 가치는 'AI 기반 정량 분석을 누구나 직관적으로 이해할 수 있게 6가지 지표로 시각화하는 것'인데, 이를 상징하는 핵심 인터페이스와 시각적 모델이 부재했습니다. 타 업체의 AI 피부 분석 솔루션이 빠르게 증가하는 상황에서, 결과 화면만 보고도 '이건 DERMA:CODE다'라고 인식할 수 있는 차별점이 필요했습니다.
- 신뢰도와 직결되는 인터랙션 품질 문제: 정적인 데이터 표시를 넘어, 결과 렌더링 성능과 인터랙션 완성도가 사용자에게 제품의 기술적 신뢰도를 형성하는 중요한 요소로 작용했습니다.
Approach & Key Contributions
DERMA:CODE 분석 결과 화면은 상담과 시술 결정에 직접적인 영향을 주는 핵심 인터페이스입니다. 단순 기능 구현을 넘어, 상담사와 환자가 각자의 맥락에서 빠르게 이해하고 의사결정을 내릴 수 있도록 UX 구조를 설계했습니다.
핵심 시각 구조 정의 — Hexa 모델 제안 및 확장
초기에는 6개의 피부 지표가 단순 리스트로 제공되어, 환자의 상태를 직관적으로 파악하고 신속하게 상담을 시작하는 데 어려움이 있었습니다.
6개의 피부 지표를 효과적으로 전달하기 위해, '육각형 인재'에서 착안한 'Hexa' 시각화 모델을 직접 제안하고 구현했습니다. 지표 간 균형 파악이 어려운 바 차트나 차별성이 부족한 레이더 차트의 단점을 보완하고자, 데이터에 따라 형태가 변하는 정육각형 UI를 고안했습니다.
환자는 직관적으로 피부 상태를 인지할 수 있게 되었고, 상담사의 설명 방식도 일관되게 표준화되었습니다. 이 모델은 결과 화면부터 디자인 시스템 전반까지 적용되며 제품의 핵심 아이덴티티로 자리 잡았습니다.
제품 초기부터 고도화까지 — 역할 확장
초기 UX 리뷰 단계부터 참여해 문제 정의를 수행했으며, V3에서는 비즈니스 요구사항 분석과 명세화, 로드맵 정의까지 담당하며 제품 방향성 수립에 기여했습니다.
복잡한 시술 프로세스의 구조화
모든 환자에게 동일한 정보를 보여주던 기존 구조에서 벗어나, 시술별 맥락에 따라 화면이 유연하게 분기되는 구조를 설계했습니다. 상담 상황에 맞는 정보를 단계적으로 제공하고, 상담 효율성과 시술 확정까지의 흐름을 개선했습니다.
두 사용자(상담사·환자)의 목표를 동시에 만족하는 인터페이스 설계
상담사는 한 화면에 많은 데이터가 동시에 노출될수록 어떤 지표부터 설명해야 할지 혼란을 느꼈고, 환자 역시 여러 수치를 한꺼번에 접하면서 설명이 생략된 영역이 있을 경우 '이 수치는 어떤 의미인가요?', '왜 이 부분은 설명하지 않나요?'와 같은 추가 질문을 자주 제기했습니다. 기존 화면에서는 모든 지표가 동시에 표시되어 상담사가 매번 설명 순서를 즉석에서 결정해야 했고, 그 과정에서 반복적인 추가 질문이 발생하며 상담 시간이 지연되는 문제가 있었습니다.
두 사용자의 요구를 감안하여, 일정한 순서를 통해 상담이 이루어지도록 를 적용하기로 했습니다.
상담사에게는 전체 데이터를, 환자에게는 단계적 정보를 제공하는 이원화된 뷰 전략을 설계했습니다. 상담사가 상담 흐름에 맞춰 Hexa 그래프로 전체 상태를 먼저 보여주며 를 형성하고, 환자가 관심을 보이는 시점에 해당 지표의 상세 데이터를 순차적으로 노출하는 구조입니다.
KPIs & Impact
- Hexa 시각 구조 도입으로 상담 시간 5–10% 단축, 핵심 지표 전달 효율 개선
- 결과 화면 개선 후 상담 중 불필요한 추가 질문 5% 감소, 이해도 향상 확인 (상담진 피드백)
- Hexa 그래프 화면과 헥사곤 패턴 등이 클리닉 SNS 콘텐츠의 주요 소재로 활용 — 테이아 클리닉에서 마케팅 자산으로 사용 중
- 프론트엔드 단독 담당으로 빠른 의사결정 구조를 구축하고 1–2주 단위 릴리즈 사이클 운영
Err Response: LCP 16.7s → 5.7s 성능 개선 (5단계 최적화)
프로덕션 환경에서 LCP 16.7초로 인해 상담 현장 사용성이 저하되는 문제를 발견하고, 5단계에 걸친 체계적 최적화를 통해 해결했습니다.
Discovery
상담 현장에서 AI 분석 결과 화면이 로딩되기까지 약 16.7초가 소요되어, 상담사가 대기 중 환자의 집중력을 유지하기 어렵다는 피드백이 발생했습니다. Chrome DevTools Performance 탭과 Lighthouse 분석 결과, 병목이 한 곳이 아니라 여러 레이어에 걸쳐 있었습니다: 분석 데이터 API 응답을 기다리는 렌더 게이트가 얼굴 이미지 렌더를 차단하고 있었고, 미사용 폰트(Geist)가 크리티컬 패스에서 2.8초를 소모했으며, 3D mesh 리소스(5.8MB)가 2D 모드에서도 다운로드되어 LCP 이미지와 네트워크 대역폭을 경쟁하고 있었습니다. 또한, 얼굴 이미지 원본이 2888×3852 JPEG(3,506KB)로 표시 크기(546×728) 대비 과도하게 큰 상태였습니다.
Response — 5단계 최적화
병목을 렌더 차단, 네트워크 경쟁, 이미지 최적화 세 영역으로 분류하고 단계적으로 개선했습니다.
분석 데이터 로딩이 완료될 때까지 전체 페이지를 차단하던 렌더 게이트를 제거하여, 얼굴 이미지가 API 응답과 무관하게 즉시 렌더되도록 했습니다. LCP 이미지에 fetchPriority='high'를 적용하고, 3D 리소스는 2D 모드에서 로딩하지 않도록 지연 처리했습니다. 분석 스크립트를 lazyOnload로 지연하고 이미지 캐시 TTL을 1시간에서 7일로 확대했습니다.
Tailwind CSS v4가 자동 포함하는 Geist 폰트가 크리티컬 패스에서 2.8초를 소모하고 있었으나, 실제 사용하지 않는 폰트여서 제거했습니다. 수치상 변화는 미미했지만 네트워크 경쟁 요소를 줄이는 정리 작업이었습니다.
⚠️ Phase 3 (14.2s → 23.7s, 역효과): 기존에 운영 중이던 다른 서비스의 3D 스캔 로딩 화면을 그대로 적용했더니, 로딩 오버레이가 LCP 이미지를 완전히 차단하여 오히려 23.7초로 악화되었습니다. 다른 프로젝트의 패턴을 맥락 없이 재사용하면 역효과가 날 수 있다는 것을 학습했습니다.
Phase 3의 실패를 분석하여 '2D 우선 렌더 + 3D 백그라운드 로딩' 전략으로 전환했습니다. 초기에는 2D 얼굴 이미지를 즉시 표시하여 LCP를 확보하고, 3D mesh가 백그라운드에서 준비되면 스캔 트랜지션 애니메이션과 함께 3D 뷰로 전환하는 구조를 설계했습니다.
얼굴 이미지를 프록시 서버에서 sharp를 사용해 WebP 변환 + 리사이즈(1092px, 2x retina 대응)하여 3,506KB → 약 100KB(97% 감소)로 최적화했습니다. 이 이미지는 Three.js에서 3D mesh에 래핑되는 텍스처 파일이라 Next.js Image나 클라이언트 Canvas 리사이즈를 적용할 수 없었고, 이미 존재하는 프록시 서버에서 서버 사이드로 변환하는 것이 유일하면서도 가장 효율적인 방법이었습니다.
Result
LCP가 16.7초에서 5.7초로 약 66% 개선되었습니다. 특히 이미지 최적화(97% 용량 감소)와 2D 우선 렌더 전략이 가장 큰 효과를 냈으며, 상담 현장에서 체감 대기 시간이 대폭 단축되어 상담 흐름이 자연스럽게 이어지게 되었습니다.
Lessons Learned
첫째, 성능 최적화는 단 한 번의 해결책이 아닌 지속적인 실험과 측정의 반복임을 체감했습니다. Phase 3에서 로딩 화면이 오히려 LCP를 경험을 통해, 타 프로젝트의 패턴을 맥락 없이 재사용하기보다 현재 서비스의 병목을 데이터로 증명하는 과정이 우선되어야 함을 배웠습니다. 둘째, 병목 현상은 코드뿐만 아니라 리소스 크기(3.5MB 이미지), 네트워크 경합(3D Mesh, 폰트, 스크립트), 렌더링 차단 요소 등 다양한 레이어에 산재해 있었습니다. 각각을 분리해서 측정하고 우선순위를 매기는 것이 핵심이었습니다.