본문으로 건너뛰기

ADR-0011: 스켈레톤을 기각하고 리졸버와 베일을 채택한다

상태

Accepted

ADR-0003의 "서버 상태 조회의 기본 수단은 httpResource" 결정을 대체합니다. httpResource는 화면 진입에 필수가 아닌 조회로 역할이 축소되며, 도구 자체를 기각하는 것은 아닙니다.

날짜

2026-08-10

맥락

데이터가 준비되기 전에 무엇을 보여줄지는 두 축의 문제입니다.

선택지
데이터를 언제 가져오는가 라우트 진입 전 리졸브 (fetch-then-render) · 렌더 후 조회 (render-then-fetch)
기다리는 동안 무엇을 보여주는가 통합 덮개(베일) · 영역별 뼈대(스켈레톤)

ADR-0003은 첫 번째 축에서 render-then-fetch를 택했습니다. 컴포넌트가 httpResource로 조회하고 로딩 상태를 화면 안에서 표현하는 방식입니다.

이 방식은 두 번째 축의 답을 각 화면에 떠넘깁니다. 화면마다 "로딩 중에 무엇을 보여줄지"를 설계해야 하고, 그 결과 같은 성격의 대기가 화면에 따라 다르게 표현됩니다. 1순위 품질 목표인 예측 가능성과 어긋납니다.

업계 기본값처럼 통용되는 스켈레톤을 채택하면 이 문제가 해결되는지 검토했습니다.

결정

데이터는 라우트 리졸버로 진입 전에 받고, 대기 표현의 기본은 베일입니다. 완성된 화면만 노출하며 반쯤 채워진 화면과 순차적 레이아웃 이동을 허용하지 않습니다.

스켈레톤은 사용하지 않습니다. 에이전트는 이 표준 안에서 스켈레톤을 제안하지 않습니다.

시간 정책은 개별 컴포넌트가 아니라 라우터 층에 겁니다.

기본 역할
--wait-delay 200ms 이 시간 안에 끝나면 베일을 띄우지 않습니다
--wait-min 400ms 띄운 베일은 최소 이 시간 유지합니다

httpResource는 화면 진입에 필수가 아닌 조회에서 계속 사용합니다. 오버레이 내부, 보조 정보 영역, 폴링이 해당합니다. 판정 기준은 화면 진입에 필수인가 하나입니다.

층별 적용 경계는 ADR-0012가 정의하며, 세부 규칙은 로딩 전략이 원본입니다.

근거의 성격

구분 내용
구조적 논거 스켈레톤은 레이아웃 이동 방지 기법이 아니라 최종 치수를 아는 경우에 한해 이동 없이 기다리는 표현입니다. 실제 화면 다수는 콘텐츠 크기가 데이터에 의존하므로 예약할 치수 자체가 없습니다
유지보수 논거 치수를 아는 경우조차 예약값(높이·행 수·줄 수)을 데이터 구조 변화에 맞춰 계속 유지해야 합니다. 예약이 어긋나는 순간 오히려 레이아웃 이동이 발생합니다
선례 여러 문서를 오가는 전통적 웹 탐색에서 브라우저는 다음 문서가 준비될 때까지 이전 문서를 유지합니다. 리졸버와 베일은 그 계약의 복원입니다
검증된 것 --wait-delay 200ms는 사용자 인지 연구와 부합합니다. 500ms 미만 구간에서는 표시자 없는 상태가 표시자보다 빠르게 느껴진다는 보고가 있으며, 200ms 지연이 이 구간을 걸러냅니다
감수하는 것 체감 속도 연구는 스켈레톤이 스피너보다 빠르게 느껴진다고 보고합니다. 본 결정의 근거는 유지보수 비용이며 체감 속도가 아니므로 연구가 결정을 반박하지는 않으나, 체감 속도 손실을 감수하는 결정임을 기록합니다

검토한 대안

스켈레톤 기본 (render-then-fetch 유지)

구분 내용
장점 빈 화면 없이 즉시 구조가 보입니다. 업계에서 익숙한 표현이며 체감 속도 연구가 유리하게 보고합니다
단점 성립 조건인 치수 예지가 실제 화면 다수에서 충족되지 않습니다. 예약이 어긋나면 오히려 레이아웃이 이동합니다. 예약값 자체가 유지보수 대상이 됩니다
기각 사유 성립 조건이 충족되지 않는 화면이 다수이고, 화면마다 예약을 설계해야 해서 로딩 표현이 화면별 판단으로 흩어집니다

하이브리드 (라우트는 리졸버, 화면 내부는 httpResource로 자유 배분)

구분 내용
장점 첫 표시가 가장 느린 요청에 묶이는 문제가 완화됩니다
단점 "어느 데이터가 핵심인가"의 판정이 화면마다 들어갑니다
기각 사유 판정 자체를 없애지 못하면 예측 가능성이 회복되지 않습니다. 다만 판정 기준을 "화면 진입에 필수인가" 하나로 고정해 이 대안의 이점을 일부 취했습니다

결과

로딩 표현을 화면마다 설계하지 않게 됩니다. 레이아웃이 한 번만 확정되어 누적 레이아웃 이동이 구조적으로 차단되고, 화면마다 치수 예약을 만들 필요가 없습니다.

감수하는 사항은 다음과 같습니다.

  • 첫 표시 시점이 가장 느린 요청에 묶입니다. 리졸버에 화면 진입 필수 데이터만 넣는 규칙과 시간 정책으로 완화합니다.
  • 체감 속도가 스켈레톤보다 불리할 수 있습니다. 근거의 성격 절에 기록한 대로 감수합니다.
  • 리졸버는 지연 로딩되지 않아 초기 번들에 포함됩니다. 리졸버를 가볍게 유지하고, 화면 수가 늘어나면 loadChildren으로 라우트 그룹을 지연 로드합니다.
  • 기존 문서 세 곳을 개정했습니다. ADR-0003의 상태, 라우팅과 네비게이션ResolveFn 배제 규칙, 서버 상태와 클라이언트 상태의 조회 모델입니다.

개정

  • 2026-08-10: 본 ADR 작성 시점에 라우팅과 네비게이션 4.3절ResolveFn 배제 규칙을 철회했습니다. 그 규칙의 근거는 "전환이 멈추고 피드백이 없다"였으나, 베일이 곧 피드백이므로 리졸버와 베일을 세트로 쓰면 성립하지 않습니다. 리졸버만 단독으로 쓰는 것은 여전히 금지합니다.
© 2026 dev.goraebap