웹 전반에 만연해진 로딩 스피너와 스켈레톤 로더의 남용이 어떻게 사용자 경험을 해치고, 성능 지표와 관행이 이를 부추겼는지 비판하며 실제 체감 반응성을 높이는 대안을 제시한다.
웹에 새로운 암이 생겼다. 적어도 20년은 됐지만, 최근 들어 전례 없는 수준으로 도처에 퍼졌다. 내가 말하는 건 _스피너_다.
_스피너_가 뭐냐고?
“spinners” can be used to show the loading state in your projects.
아직도 모르겠어? 보여주겠다. 이건 세계에서 가장 사용자 중심인 회사™의 최신 최첨단 UX 연구 결과물이다. Alphabet Google 말이다.

꼬불꼬불 스피너는 진짜가 아니야. 날 해칠 수 없어.

영국 내무부(United Kingdom Home Office)의 “User-Centred Design Manual”에 있는 이게 더 낫나:
Loading spinner Tell a user they need to wait, because something is happening.
내가 뭘 클릭하든, 세상 모든 웹사이트는 매번 이렇게 한다:

적어도 언제 스피너를 써야 하는지에 대한 지침은 있다(강조는 내가 함):
Use a loading spinner to inform users they need to wait for something to happen. For example, you can use a loading spinner to show that a result is taking time to process.
Consider whether the speed and responsiveness of the service can be technically improved before using a loading spinner.
그런데 이게 대체 무슨 일이지? 왜 요즘 웹의 새로운 기본값은 가능한 한 빨리 더미 HTML 페이지를 내보내고, 사용자가 스피너 15개랑 스켈레톤 로더를 멍하니 보게 만드는 것처럼 느껴질까. “스켈레톤 로더”가 뭐냐고? 알잖아, 회색 박스들이 잔뜩 번쩍거리는 그거:

왜 이런 사용자 적대적 디자인이 모든 걸 집어삼켰을까? 어떤 사람들은 그냥 “Big JavaScript”의 음모라고 말할지도 모른다. 간결한 HTML 파일과 단순한 시맨틱 마크업 대신, 블로그 글 하나 렌더링하려고 JavaScript 80MB를 실어 나른다. 적어도 부분적으로는 맞는 말이라고 생각한다. 하지만 이건 닭이 먼저냐 달걀이 먼저냐 문제이기도 하다. 로더 클래스를 토글하고 진짜 콘텐츠가 로드됐는지 감지하는 데 JS가 몇 메가바이트나 필요하겠어?
좀 더 구체적으로는 두 가지를 지목할 수 있다.
첫째, “Doherty Threshold”다. 내가 보기엔 사실이라기보다 허구에 가깝다. 이름도 당당한 “Laws of UX”에 있는 요약은 이렇다.
In 1982 Walter J. Doherty and Ahrvind J. Thadani published, in the IBM Systems Journal, a research paper that set the requirement for computer response time to be 400 milliseconds, not 2,000 (2 seconds) which had been the previous standard. When a human being’s command was executed and returned an answer in under 400 milliseconds, it was deemed to exceed the Doherty threshold, and use of such applications were deemed to be “addicting” to users.
Laws of UX, Doherty Threshold↗
와, 엄청 과학 같고, 내 2008년 Facebook 프로필이 자랑스럽게 말하듯이 “I F***ing Love Science!”지! 자, 출처도 인용도 없는 연구 논문? 그게 _과학_의 정의가 아니면 뭐가 과학이겠어!
2026년, 우리 주님의 해에 “addicting”이라는 표현이 썩 좋아 보이진 않을지도↗. 아니면 그게 Meta의 진짜 죄일지도 모르지 — 400ms 미만의 Dohrety Threshold를 마스터한 것! 바로 그거야, 그들이 그렇게 한 거야, 난 확신해. _Laws of UX_를 읽고 모든 앱의 모든 페이지 요소에 스피너를 추가한 거지. 스피너가 얼마나 오래 돌든 상관없어, 인터페이스는 반응적인 것으로 판정됐고 사용자는 중독됐다. 나도 그 비법을 참고해야 하나.
농담은 접고, 내가 말하려는 건 어느 순간부터 우리가 “유용한 반응”보다 “어떤 반응이든 일단 반응”을 더 가치 있게 여기기 시작했다는 거다. 그리고 내 두 번째 포인트가 진짜 연기 나는 총이라고 생각한다: Google Core Web Vitals (CWV)↗.
그 페이지는 그냥 직접 가서 읽어봐야 한다. 요약하자면, Google은 웹 페이지가 얼마나 “빠르게” 로드되는지로 순위를 매기기 위한 통계 지표 묶음을 사용한다. “Largest Contentful Paint” 같은, 사용자가 페이지에서 콘텐츠를 보기까지 얼마나 걸리는지를 재는 아주 구체적인 데이터 포인트들을 본다.
이제 Google 알고리즘의 구체를 논할 땐 중요한 단서가 필요하다. 우리는 실제로 어떻게 동작하는지 모른다. Google은 알고리즘을 불투명하게 유지하며, 어떤 지표든 알려지면 조작될 수 있다는 전제하에 “security by obscurity” 모델을 취한다. 한때는 스피너와 스켈레톤을 통한 “가짜 로딩”을 알고리즘이 제대로 감지하지 못했을 가능성이 크다. 지금은 훨씬 잘 처리할 거라고 추측한다. 하지만 피해는 이미 발생했다.
개발자와 UX 리서처 팀들은 웹 페이지의 “반응성”을 부정확하게 측정하는 도구들을 활용했다. 나 자신도 프로덕션 앱에서 Chrome Lighthouse를 돌리며, 자산의 총 용량을 줄이고 Google이 “좋다”고 여기는 몇 가지 핵심 지표를 최적화하려고 수많은 시간을 썼다. 그렇다고 그게 전부 헛수고였다는 말은 아니다.
내 커리어 동안, 수많은(사실상 모든) 지표가 조작되고 남용되어 결국 그 지표가 아무 가치도 못하게 되는 걸 봐 왔다. 이건 흔히 “Goodhart’s law”↗라고 부르는 현상이다. Wikipedia 문서에는 좋은 요약이 있다: “측정치가 목표가 되는 순간, 그 측정치는 더 이상 좋은 측정치가 아니다.”
그래서 목표는 “Google에서 좋은 숫자”가 되었고 “좋은 사용자 인터페이스”가 아니게 됐다. 시간이 지나면서 사람들이 좋은 UX 연구를 올바르게 디자인에 적용하자, cargo cult↗ 효과가 “스피너를 보여줘라, 좋은 앱은 스피너를 많이 쓰니까”로 변했다. 어딘가에서 우리는 우리가 실제로 하려던 게 뭔지 놓쳐버렸다.
디자이너 팀들이 자기 힘에 취해서 “더 나은 UX”라는 명목으로 내 항문을 한 바퀴 도는 벌레 애니메이션을 디자인하고 구현하는 데 시간을 쓰고 있다.
이 불평은, 내가 실제로 써 봤고 스피너를 아무 데나 던져놓지 않으면서 실제 반응성을 높이는 데 도움이 될 수 있다고 느낀 몇 가지 불릿 포인트로 마무리하겠다.
불평 끝! 개인적으로 받아들이지 말아줬으면 한다. 나도 이 주제에 적어도 조금은 과하게 열정적이라는 걸 알고, 대부분의 사람에게 스피너 몇 개가 몇 초 뜨는 건 별일 아닐 수도 있다는 것도 안다. 다만 나는 우리가 웹 개발자로서 더 나아질 수 있다고 생각한다. 경험 좀 있는 사람이라면, 젊은 친구들이 어떤 대안이 있는지 알 수 있게 도와줘라. claude가 뚝딱 뽑아냈다고 해서 그게 맞는 건 아니다. 나는 완벽이 아니라 탁월함을 지향해야 한다고 믿는다. 나는 완벽하지 않다. 이 사이트도 완벽하지 않다. 하지만 나는 조금씩이라도 탁월해지려고 노력한다.