Lottie Inspector

Lottie가 안 움직일 때 — 단계별 디버깅 체크리스트

DEBUG

Lottie 문제의 디버깅은 결국 하나의 질문으로 수렴합니다 — "파일 문제인가, 런타임 문제인가, 내 코드 문제인가?" 이 순서대로 좁혀 가면 대부분 30분 안에 원인을 찾습니다.

1단계 — 파일 자체를 격리 검증

가장 먼저 앱·코드에서 분리해 파일만 검증합니다. 문제의 파일을 Lottie Inspector에 넣어 보세요.

2단계 — 파일이 문제일 때

JSON이 유효한가

의외로 흔합니다. 이메일·메신저를 거치며 파일이 잘리거나, 텍스트 에디터가 인코딩을 바꿔 버린 경우입니다. JSON 파서에 넣어 문법 오류부터 확인하세요.

Lottie 데이터가 맞는가

Lottie JSON은 최상위에 v(버전), fr(프레임레이트), ip/op(시작/끝 프레임), layers 키를 가집니다. 이 구조가 없다면 Lottie 파일이 아닙니다.

미지원 기능을 쓰지 않았는가

특정 레이어만 안 보인다면 십중팔구 지원 경계 문제입니다 — 이펙트, 3D, 루마 매트, 표현식. 내보내기 체크리스트의 표를 참고해 해당 레이어를 다른 방식으로 다시 만들어야 합니다.

3단계 — 런타임/코드가 문제일 때

웹 (lottie-web)

// 로드 실패는 조용히 지나가기 쉽습니다 — 이벤트를 걸어 두세요
anim.addEventListener("data_failed", () => console.error("lottie: load 실패"));
anim.addEventListener("error", (e) => console.error("lottie:", e));

iOS (lottie-ios)

Android (lottie-android)

4단계 — "특정 기기에서만" 문제

재현 최소화 원칙 — 버그 리포트를 보낼 때는 "앱에서 안 나와요"가 아니라 "이 파일이 X 런타임 Y 버전에서 이렇게 나온다"까지 좁혀서 전달하세요. 파일 격리 검증(1단계)만 해도 리포트의 질이 완전히 달라집니다.

실전 사례: 30분 디버깅 로그

위 체크리스트를 실제로 어떻게 굴리는지, 제가 최근에 겪은 사례 하나를 시간 순서대로 따라가 보겠습니다. 제가 만드는 CGM 앱의 기록 화면에는 데이터 동기화 중임을 표시하는 작은 로딩 Lottie가 셀마다 들어가는데, QA에서 "스크롤을 내렸다 올리면 일부 셀의 애니메이션만 멈춰 있다"는 리포트가 올라왔습니다. 전부 멈추는 것도 아니고 특정 셀만, 그것도 스크롤 후에만 멈추니 처음 보면 꽤 당황스러운 증상입니다.

0~5분: 1단계, 파일 격리

먼저 해당 JSON을 앱에서 꺼내 뷰어에 넣어 봤습니다. 잘 돕니다. 파일 문제가 아니라는 뜻이므로 2단계는 통째로 건너뛰고 바로 3단계로 갑니다. 여기에 5분을 써서 "파일은 정상"이라는 확신을 얻은 것이 이후 25분을 절약해 줬습니다. 이 확신이 없으면 코드를 보다가도 자꾸 파일을 의심하게 됩니다.

5~20분: 3단계, 코드 추적

번들 타겟 누락이라면 처음부터 아예 안 나와야 하는데, 이 건은 처음엔 나오다가 멈추는 것이므로 로드 문제는 아닙니다. 재현 조건이 "스크롤 후"라는 점에서 셀 재사용을 의심했습니다. lottie-ios의 LottieAnimationView는 뷰가 윈도우에서 떨어져 나가면 — 즉 셀이 화면 밖으로 나가면 — 재생을 멈추는데, 그 셀이 재사용되어 화면에 돌아올 때 play()를 다시 호출하지 않으면 마지막 프레임에 멈춘 채로 보입니다. 제 코드는 cellForItemAt에서 셀을 만들 때 한 번만 play()를 부르고 있었습니다. 재사용된 셀은 이 경로를 다시 타지 않으니 정확히 리포트된 증상이 됩니다.

// 수정: 셀이 화면에 나타날 때마다 재생을 보장
func collectionView(_ cv: UICollectionView,
                    willDisplay cell: UICollectionViewCell,
                    forItemAt indexPath: IndexPath) {
    (cell as? SyncingCell)?.animationView.play()
}

20~30분: 4단계, 기기 확인

수정 후에는 보급형 테스트 기기와 최신 기기에서 각각 스크롤을 오래 반복하며 멈춘 셀이 다시 생기는지, 프레임 드랍이 새로 생기지는 않는지 확인했습니다. 셀마다 play()를 다시 부르는 비용이 걱정됐지만, 제 프로젝트 기준으로는 체감되는 차이가 없었습니다. 다만 앱을 백그라운드에 보냈다 돌아올 때도 같은 증상이 나면 그건 셀 재사용이 아니라 backgroundBehavior 설정 쪽을 봐야 하는 별개 문제입니다.

돌이켜 보면 이 건이 30분 안에 끝난 이유는 순서를 지켰기 때문입니다. 파일 탓인지 코드 탓인지 모른 채 코드부터 뒤졌다면 애먼 렌더링 엔진 설정을 바꿔 보며 한나절을 썼을 겁니다. 증상이 아무리 이상해 보여도 1단계 격리 검증부터 시작하는 습관이 결국 가장 빠릅니다.