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배제 규칙을 철회했습니다. 그 규칙의 근거는 "전환이 멈추고 피드백이 없다"였으나, 베일이 곧 피드백이므로 리졸버와 베일을 세트로 쓰면 성립하지 않습니다. 리졸버만 단독으로 쓰는 것은 여전히 금지합니다.