프로젝트를 진행하면서 한 페이지에 요청하는 API가 많거나, 불러와야 할 데이터가 많은 경우에 사용자 경험을 어떻게 개선할 수 있을까 고민했다. 예를 들어서 앱에 필요한 패키지를 다운로드하거나 파일을 업로드할 때 단순 로딩 이펙트보다는 어떤 작업을 처리하고 있는지 표시하면, 확실히 기다림이 줄었다. 유튜브 같은 경우 메인 화면에서 영상이 불러오기 전에 스켈레톤 화면을 보여주는데, 그렇게 많은 데이터를 불러오면서도 로딩 시간이 길다곤 전혀 느껴지지 않았다. 그래서 다양한 서비스에서 이러한 스켈레톤 화면을 어떻게 활용하고 있고 사용자 경험을 개선하기 위해서 어떤 노력을 하고 있는지 궁금해 대표적으로 카카오페이 사례를 알아보았다.
카카오페이에서 스켈레톤 화면을 활용하는 방법
카카오페이는 아래와 같이 Progress Indicator의 지침을 따른다고 한다.
Progress Indicator와 관련된 주요 지침은 다음과 같습니다.
1. 약 1초 이상 걸리는 작업에는 Progress Indicator를 사용하십시오.
2. Loop Animation은 빠른 동작에만 사용하십시오.
3. Percent-done Animation은 10초 이상 걸리는 작업에 사용하십시오.
4. Static Indicator는 사용하지 마십시오.
1초 미만의 지연 시간에는 스켈레톤 화면 등과 같은 애니메이션을 넣지 않는다. 그 이유는 애니메이션으로 인해서 앱 자체가 산만하고 복잡해질 수 있기 때문이다. 실제로 사용해보니, 공지사항과 같이 API가 복잡하지 않고 지연시간이 1초 미만인 경우에는 스켈레톤 화면이 없었지만, 그 외 메인화면, 설정화면에는 모두 로딩 이펙트나 스켈레톤 화면이 있었다. 또 사용자가 한 번 들어가서 API가 호출된 화면에 대해서는 재접속해도 새로고침되지 않고 아래로 스크롤을 내려 직접 새로고침하도록 하는 방식이었다.
실제로 카카오페이에서는 API 응답 시간이 기준보다 길 때는 스켈레톤 화면을, 기준보다 짧은 경우엔 바로 데이터를 보여주도록 설계해 사용한다. 이러한 작업을 React Suspense로 쉽게 설정할 수 있다. 물론 Suspense를 사용하지 않고도 모든 컴포넌트에서 setTimeOut을 사용하거나 custom hook을 사용할 수 있지만 추후 유지보수가 어렵다는 측면을 인해 이 방법을 택한다고 한다.
const DeferredComponent = ({ children }: PropsWithChildren<{}>) => {
const [isDeferred, setIsDeferred] = useState(false);
useEffect(() => {
// 200ms 지난 후 children Render
const timeoutId = setTimeout(() => {
setIsDeferred(true);
}, 200);
return () => clearTimeout(timeoutId);
}, []);
if (!isDeferred) {
return null;
}
return <>{children}</>;
};
<Route exact path={ROUTE.CATEGORY_LIST}>
<Suspense
fallback={
<DeferredComponent>
<HomeSkeleton />
</DeferredComponent>
}
>
<CategoryList />
</Suspense>
</Route>
DeferredComponent는 children을 Props로 받고, 200ms이 지나기 전에는 children을 화면에 렌더하지 않는 컴포넌트이다. Suspense의 fallback으로 내린 스켈레톤을 이 컴포넌트로 한번 감싸 특정 시점이 지난 후 스켈레톤을 보여주도록 한다.
추가로, 카카오페이에서는 Firebase Performance Monitoring를 사용해서 다양한 성능 지표를 수집하고 있다. 평균적인 API 응답/지연 시간을 측정해서 스켈레톤 화면을 보는 사용자의 수를 줄여나가고 있다고 한다.
결론
사용자 경험을 개선하기 위해서 스켈레톤 화면도 적절히 사용하는 것이 좋다. 로딩 시간이 짧을 땐 애니메이션을 줄이고, 로딩 시간이 길 때는 애니메이션을 추가해 로딩 시간을 실제보다 짧게 느껴지도록 해야 한다. 실제로 내가 투입된 프로젝트에서 사용자에게 매번 새로운 데이터를 보여주기 위해서 페이지에 들어갈 때마다 새롭게 API를 받아오도록 설계했는데, 카카오페이처럼, 처음에 API를 가져오고, 위에서 아래로 내렸을 때 새로운 데이터를 가져와 API 호출을 줄여야 겠다고 생각했다.
'FrontEnd > React-native' 카테고리의 다른 글
react-native 애플리케이션 성능 개선하기(feat.useQuery) (0) | 2024.08.22 |
---|---|
Axios 인터셉터로 JWT 로테이션 구현하기 (0) | 2024.08.22 |
중첩 네비게이션에서 발생하는 Stack 초기화 문제 해결(feat.CommonAcitons) (0) | 2024.08.22 |