하이브리드 WebView 앱 (웹 영역)
Next.js WebView 웹과 React Native가 브릿지로 통신하는 하이브리드 구조에서, 웹과 네이티브가 얽혀 웹 코드만으로는 풀리지 않는 문제들을 주로 다뤘습니다.
- 기간
- 2026.01 ~ 진행 중
- 역할
- WebView 웹 담당 (+ 모바일 공통 로직 일부, 약 2개월)
- 기여
- 웹 커밋의 약 55% 기여
- 팀
- 웹/모바일/백엔드 협업 (모바일 메인 개발자 별도)
첫 로드 스크립트 gzip −30%화면 멈춤 시간(TBT) −54%목 분기 5,164줄 삭제단위 테스트 104개
인증 아키텍처WebView 브릿지MSW · VitestNext.js 16 (App Router)Zustand (persist)ethersMSW



스토어 공개 이미지
—
구조
01
주요 기여
항목을 누르면 상세 내용이 열립니다
네이티브 브릿지 기반 토큰 인증 설계 — 무한 재요청 루프를 401 기준 갱신으로 차단
- WebView는 쿠키 세션을 믿을 수 없는 구조 → 브릿지로 토큰을 받아 전 요청에 자동 주입
- 동시다발 401은 재발급 1회로 합침(single-flight), 리프레시 만료 시 자동 재로그인 연결
- 서버가 이미 거부한 토큰을 '만료 전'이라며 재사용하던 무한 재요청 루프 발견 → 401 응답 기준 강제 갱신으로 해결
앱-웹 브릿지 구축 — Promise 기반 appBridge, 안드로이드 백버튼 연동은 RN까지 직접 구현
- 손으로 호출하던 postMessage를 Promise 요청-응답 구조의 appBridge로 통일, 모달·토스트 등 네이티브 액션 연동
- 안드로이드 백버튼이 웹 화면 상태를 따르도록 requestId 기반 브릿지를 RN까지 직접 구현 (300ms 타임아웃 안전장치, EAS Update로 배포)
- 웹 모달이 네이티브 탭바를 못 덮는 한계 → 꼭 필요한 모달만 브릿지 액션으로 네이티브 전환, 기기·OS별 safe-area 차이는 플랫폼 분기로 흡수
NFT 전송 화면 — 요청부터 푸시 완료까지 진행 상태를 화면이 직접 관리
- 전송 완료가 서버 응답이 아니라 푸시 알림으로 오는 구조 → 전송 건을 저장해 두고 요청·처리 중·완료 상태를 관리
- 전송 중인 NFT는 목록에 '전송 중'으로 표시하고 재진입을 막아 중복 전송 방지, 상태별 만료 처리(요청 5분·처리 중 24시간)로 갇힘 방지
- 목록 데이터(인덱서)가 체인보다 늦을 수 있어, 전송 직전 온체인 소유자를 다시 확인해 가스비만 잃는 전송을 차단
성능 실측 개선 — First Load JS gzip −27.6%, TBT −54% · 목 분기 5,164줄 MSW 일원화
- 초기 번들 분석으로 lottie·Sentry Replay·framer 엔진을 찾아 지연 로드로 전환 — 개선 전후를 같은 조건에서 실측 (511→370KB, 968→445ms)
- 프로덕션 코드 곳곳의 목 분기를 MSW 인터셉트 한곳으로 통합, 런타임 시나리오 패널로 엣지 케이스를 클릭으로 재현
- 번들에 실리던 목 데이터를 dynamic import로 격리해 First Load JS 약 99KB 추가 감축
핵심 로직을 Vitest 테스트 104개로 고정 — 도입 첫날 로그아웃 버그 적발
- 토큰 single-flight, 브릿지 타임아웃 등 트러블슈팅으로 세운 규칙을 11개 파일·104개 테스트로 고정
- 도입 첫날, 빈 바디 5xx 응답이 '만료'로 오분류돼 로그아웃되던 버그를 테스트가 발견 → 즉시 수정
- 테스트는 커버리지 숫자가 아니라 정책을 고정하는 도구라는 확신을 얻음
02
대표 트러블슈팅
모노레포 React 중복으로 인한 "Invalid hook call"
코드 변경 없이 앱이 깨진 원인이 번들에 두 벌 들어간 React임을 찾아, 모든 import가 루트 React 하나만 보게 막아 해결. 자세히 →
WebView 모달 dim이 네이티브 탭바를 못 덮는 문제
전부 동기화하는 방안은 비용 대비 효과가 낮아 접고, 꼭 필요한 모달만 네이티브로 전환. 자세히 →
로그인 후 뒤로가기가 온보딩으로 돌아가던 문제
로그인 후 뒤로가기가 온보딩으로 되돌아가던 문제를 라우팅 방식을 바꿔 구조적으로 제거. 자세히 →
WebView access-token 무한 재요청 루프
만료 시각 계산 대신 서버 응답(401)을 기준으로 재발급하게 바꿔 무한 루프를 끊음. 자세히 →
Sentry 에러 수집 사각지대 해소
NFT 전송에만 붙어 있던 Sentry를 전체 API·인증 흐름으로 넓히고, 잡을 에러와 버릴 에러의 기준을 세움. 자세히 →