사용자 경험에 맞춰 Skeleton UI 적용하기

제리추·2024년 1월 22일
24
post-thumbnail

🐹 들어가기 앞서

사용자 경험을 개선하기 위해 비동기로 데이터 패칭할 상황에서 스켈레톤 UI를 많이 적용합니다. 그런데 모든 상황에서 스켈레톤 UI를 적용하는 것이 사용자 경험 개선에 도움이 될까요?

1) 엘레베이터 거울 효과

엘레베이터에 거울은 왜 설치되어 있을까?

1853년 미국에서 고층 빌딩들이 우후죽순 생겨났고 엘레베이터 세계기업인 오티스는 최초로 안전 장치가 부착된 엘레베이터를 납품하게 됐습니다. 하지만 당시 기술력으로 엘레베이터의 속도는 빠르지 않았고 너무 느리다는 불만은 많았지만 당시 기술력으로 더는 엘레베이터를 빠르게 할 수 없었습니다.

이 문제를 해결하기 위해 엘레베이터에 거울을 설치해보자는 아이디어가 등장했습니다. 엘레베이터에서 거울을 보며 옷단장을 한다면 사람들이 엘레베이터 속도에 대한 체감이 덜해질 것이라고 생각했습니다.

이 아이디어는 성공적이었고, 이 때부터 엘레베이터에 거울을 설치하는 것은 공식화 됐습니다.

여기서 엘레베이터 거울은 Skeleton UI와 같습니다. 실제 조사에 따르면 Skeleton UI를 설정한 웹 사이트의 사용자 이탈률이 현저히 적다고 조사되었습니다.

엘레베이터 거울 == Skeleton UI, 엘레베이터 속도 == API 지연 속도

2) Skeleton UI란?

skeleton

비동기로 데이터 패칭 후 로딩 상황 속에서 실제 데이터가 렌더링 될 화면의 윤곽을 보여주는 애니메이션 UI

3) Skeleton UX 연구 결과

닐슨 노먼 그룹 연구 결과에 대한 글을 참고하자면

  1. 이벤트가 발생한 즉시 피드백을 제공하세요.
  2. 1초 이상 걸리는 작업에는 스켈레톤 UI를 제공하세요.
  3. 움직이지 않는 스켈레톤 UI는 사용하지 마세요.
  4. 스켈레톤 UI에 다시 클릭하지마세요 문구: 사용하지 마세요.

1. 이벤트가 발생한 즉시 피드백을 제공하세요.

예로 인스타에 사진 업로드 버튼을 눌렀을 경우 아무 반응이 없다면 사용자들은 제대로 눌려지지 않았다고 생각해 여러번 더 클릭할 것입니다. 따라서 마우스 클릭, 키보드 다운 이벤트 발생 즉시 loading 처리 및 스켈레톤 처리를 진행하라는 것을 의미합니다.

2. 1초 이상 걸리는 작업에는 스켈레톤 UI를 적용해주세요. 적용 방법은 두가지의 방식이 있습니다.

예로 웹사이트를 방문할 때 그 웹사이트에 지연이 오래된다면 사용자들은 그 웹사이트에 대한 호감이 떨어지고 이탈하게 됩니다. 이러한 이슈를 분산 시키기 위해 spinner 또는 Skeleton ui를 설정하는 방법이 두 가지 있습니다.

스피너
첫번째 반복 애니메이션 스켈레톤은 2~10초 지연시간이 길지 않을 때 설정해야합니다. 지연 시간이 10초 이상일 경우 반복되는 spinner나 Skeleton UI를 사용하게 되면 사용자가 웹 사이트가 진행되지 않는 것처럼 느끼며 이탈하는 상황이 발생합니다.

로딩바
10초 이상인 경우는 완료율이 있는 로딩바를 설정합니다. 현재 진행 상황을 예상 단위 및 단계로 표시합니다. 일반적으로 10초 이상되는 긴 지연 시간일 경우 사용합니다. 이로써 사용자 웹사이트 이탈률을 감소시킵니다.

마지막으로 지연시간이 1초 미만일 경우 Skeleton UI를 설정하게 된다면 오히려 깜빡이는 UI가 UX를 해치게 되기 때문에 사용하지 않습니다.

3. 정적인 Skeleton을 사용하지 마세요.

움직이지 않는 스켈레톤을 사용하는 경우 피드백이 없는 것보다 낫겠지만 어떤 일이 일어나고 있는지 사용자가 정확히 알 수 없기 때문에 사용하는 것을 지양합니다.

4. 다시 클릭하지마세요 경고 문구를 사용하지 마세요.

최악의 Skeleton UI는 '다시 클릭하면 추가 금액이 소비됩니다.'와 같이 사용자를 위협하는 문구가 들어 있는 사이트입니다. 친화적인 디자인은 사용자를 불안하게 하지 않습니다.

🐹 Skelton UI 적용해보기

1) Skeleton UI 비교

코드를 적용하기 전에 두가지의 Skeleton UI 보자.


어떤 것이 더 자연스러워 보이시나요?

저는 아래 스켈레톤이 더 자연스러워 보입니다! 위와 같은 경우 지연 시간이 짧아 Skeleton ui가 들어갈 경우 화면이 덜그럭 거린다는 인상을 주게 됩니다.

그렇다면 연구 결과와 같이 1초 미만일 경우에 Skeleton이 보이지 않게 하고 이상일 때는 Skeleton ui가 보일 수 있도록 하는 deferredComponent를 만들어 봅시다.

2) Suspense, DeferredComponent 함께 적용하기

import { PropsWithChildren, useEffect, useState } from 'react';

// ** 지연시간 200ms 미만일 때 스켈레톤 미노출 / 200ms 이상일 때 스켈레톤 노출 **
const DeferredComponent = ({ children }: PropsWithChildren) => {
  const [isDeferred, setIsDeferred] = useState(false);

  useEffect(() => {
    const timeOut = setTimeout(() => {
      setIsDeferred(true);
    }, 200);
    return () => clearTimeout(timeOut);
  }, []);

  if (!isDeferred) return null;
  return <>{children}</>;
};

export default DeferredComponent;

DeferredComponent를 사용하여 200ms 의 제한을 두고 화면을 띄우는 컴포넌트를 만들었습니다. 그럼 DeferredComponent를 Suspense에 적용해보겠습니다.

return (
    <div>
      <Tab tabInfo={tabInfo} />
      <div className={cx('container-flex-box')}>
        <Suspense
          fallback={
            <DeferredComponent>
              <div className={cx('container-flex-box')}>
                {[...new Array(6)].map((_, idx) => (
                  <SkeletonCard key={idx}></SkeletonCard>
                ))}
              </div>
            </DeferredComponent>
          }
        >
          <OperatedCardList operatedCardListProps={operatedCardListProps} />
        </Suspense>
      </div>
    </div>
  );

React Suspense fallback에 적용했습니다. 적용한 UI를 확인해보면 UX가 확실하게 개선이 됐다는 것을 느낄 수 있습니다.

하지만 지연 시간이 1000ms 일 경우 1000-200= 800ms 의 Skeleton UI를 보여주고 만약 250ms 일 경우 50ms 스켈레톤 UI를 보여주게됩니다. 그렇다면 똑같은 문제가 아닐까요?

그렇기 때문에 각각의 플랫폼의 API 평균 지연시간을 체크한 후 가장 많은 사람들을 개선할 수 있는 시간을 찾아 적용하면 많은 사람들에게 사용자 경험을 개선 시킬 수 있습니다.

🐹 결론

상황에 따라 그리고 각각의 플랫폼 평균 지연시간에 따라 Skeleton UI를 지정해주자.

🐹 Reference

profile
안녕하세요. 소프트웨어 엔지니어 제리입니다 🐹

2개의 댓글

comment-user-thumbnail
2024년 11월 18일

잘봤습니다~
근데 return () => clearInterval(timeOut); 이부분은 clearInterval이 아니라 clearTimeout이 아닌가여?

1개의 답글