대니
danny's blog@dannywon_dev
발행 138 · 대기 180

1인 개발자. 클로드 코드를 팀처럼 굴린다. 매일 겪은 것만 쓴다.

← 클로드 코드

requestAnimationFrame 45초 타임아웃과 빈 스크린샷

저장된 204칸이 비어 보였다. 앱 버그가 아니라 자동화가 연 탭이 다시 그리기를 미룬 탓이었다

브라우저 자동화로 화면을 열어 스크린샷을 찍었는데 빈 화면이 나오면, 보통 앱을 의심한다. 나도 그랬다.

2026-08-25. 아트페어 부스 배치도를 다루는 관리자 화면에서 저장된 204칸이 「비어있어요」로 뜨는 문제를 쫓았다. 볼트 문서에는 이미 이렇게 적혀 있었다.

첫 마운트마다 항상 재현되는 진짜 버그, 원인 미상

나흘 묵은 기록이었다. 자동화로 열어 스크린샷을 찍으니 그대로였다 — 빈 화면에 「첫 항목 만들기」 버튼. 두 번 재현했다.

그런데 같은 페이지에서 자료를 하나씩 재보니 전부 정상이었다.

  • 서버가 보낸 응답에 좌표 204개
  • 화면 컴포넌트가 받은 값도 204칸
  • 브라우저 안 상태 저장소도 204칸
  • 콘솔 에러 0
  • 그리고 결정적으로 — DOM 에 사각형이 756개 있었고, 「비어있어요」라는 글자는 DOM 에 아예 없었다

화면에 보이는 그 문구가 HTML 안에 없었다. 그 시점에 앱 버그 쪽은 접었다.

중간에 한 번 더 틀렸다

페이지가 멈춘 건지 보려고 requestAnimationFrame 을 기다렸다. 45초 타임아웃이 났다. 그걸 「렌더러가 얼어붙었다」고 읽었다.

아니었다. 백그라운드 탭에서는 그 콜백이 원래 안 돈다. 멈춘 증거로 쓴 것이 애초에 증거가 될 수 없는 값이었다.

진짜 원인은 이거였다. 자동화가 여는 탭은 브라우저가 「보이지 않는 탭」으로 판정해서 다시 그리기를 미룬다. 그래서 스크린샷이 로딩 직후의 빈 프레임을 그대로 붙잡고 있었다. 자료는 다 도착해 있었고 화면 픽셀만 낡은 것이었다.

마우스를 한 번 올리자 그 자리에서 204칸이 떴다.

「다른 화면 갔다 오면 정상이더라」는 우회법도 같은 착시였다. 그 화면이 고친 게 아니라 클릭이 다시 그리기를 부른 것뿐이었다.

바꾼 것

관측 규칙을 하나 추가했다. 비어 보이면 픽셀 말고 DOM 으로 판정한다.

  • 요소 개수를 센다 (document.querySelectorAll('rect,li,tr').length)
  • 화면에 보이는 그 문구가 HTML 안에 실제로 있는지 확인한다
  • 찍기 전에 마우스를 한 번 올려 다시 그리기를 부른다
  • requestAnimationFrame 을 대기 조건으로 쓰지 않는다

거꾸로도 참이라는 걸 같이 적었다. 정상으로 보이는 화면도 내가 방금 클릭한 덕일 수 있다. 그래서 무엇을 눌러서 그렇게 됐는지를 같이 기록하게 했다.

남은 것

그날 확인 결과 진짜 버그도 따로 있었다. 다른 저장 방식으로 만든 배치도는 실제로 빈 화면이 떴다. 착시 하나와 진짜 하나가 같은 증상으로 섞여 있었다.

문서는 「앱 버그」에서 「착시」로 고쳤다가, 다시 「절반은 착시, 절반은 진짜」로 두 번 고쳤다. 한 번에 맞게 적으려 하지 말고 틀린 걸 알았을 때 그 자리에서 고치는 쪽이 빨랐다.

← 목록으로