스켈레톤 로딩 지연

유의진·2024년 12월 24일
0

찍찍이

목록 보기
3/6
post-thumbnail

스켈레톤 로딩이란?

빈 화면 대신, 어떤 형식으로 콘텐츠가 자리잡을지 구조적으로 미리 보여주는 로딩이다.
사용자에게 로딩을 납득할 수 있는 충분한 정보를 제공한다.

장점

체감 로딩 시간이 짧다.

스피너 로딩과의 차이점

  • 대부분의 스피너 로딩은 짧은 로딩 시간에 사용한다.
  • 동적인 요소로 사용자가 지루함을 느끼지 않게 한다.
  • 체감 로딩 시간이 길다.

Progress Indicator

UX 리서치 그룹 닐슨 노먼의 지침
https://www.nngroup.com/articles/progress-indicators/

주요지침

약 1초 이상 걸리는 작업에는 Progress indicator를 사용
Loop Animation은 빠른 동작에만 사용
Percent-done Animation은 10초 이상 걸리는 작업에 사용
Static Indicator는 사용 X

이 글에서 진행 상태 표시기의 유형은 두 가지로 나누어진다.

불확정적 로딩(Indeterminate Loading)

  • 진행 시간이 예측 불가능할 때 사용.
  • 보통 회전하는 스피너(spinner) 형태.
  • 사용자가 작업이 진행 중이라는 사실만 알 수 있음.
  • 하지만 정확한 완료 예상 시간을 제공하지 않으므로 답답함을 유발할 수도 있음.

확정적 로딩(Determinate Loading)

  • 예상 완료 시간을 제공할 수 있을 때 사용.
  • 보통 프로그래스 바(progress bar) 형태.
  • 완료 예상 시간을 보여줘 사용자의 기대 관리를 돕고, 신뢰감을 형성.

그중에서 스켈레톤 로딩은 불확정적 로딩에 들어간다. 왜냐하면 "현재 데이터를 불러오는 중"이라는 시각적 힌트를 제공하지만, 정확한 진행률을 보여주지는 않기 때문이다.

UX 최적화를 위해 스켈레톤 로딩을 적용하는 방법

  • 실제 콘텐츠와 유사한 형태로 디자인할 것
  • 너무 오래 표시되지 않도록 할 것
  • 중요한 정보는 먼저 로딩할 것
  • 부드러운 페이드 인 효과 적용

결론적으로 스켈레톤 로딩을 적용하게 되면 사용자가 콘텐츠의 구조를 빠르게 파악할 수 있고, 스피너보다 기다리는 시간을 짧게 느끼게 할 수 있다.

카카오페이의 스켈레톤 지연 시간

카카오페이의 어떤 서비스의 네트워크 요청 응답 시간 지표에서 평균적으로 110ms의 지연 이후 API 응답을 받고 있고, 75%의 사용자들은 192ms 이내에 응답을 받고 있다.

그렇기 때문에 200ms 정도를 지연시켜 사용자에게 노출한다면 약 75%의 사용자는 덜그럭 거리지 스켈레톤을 보여주지 않을 수 있다.
그렇지만 덜그럭거림을 느끼지 못하던 15%의 사용자는 덜그럭거리는 스켈레톤 뷰를 보게 된다는 단점이 있다.

그럼에도 카카오페이에서는 스켈레톤을 200ms를 지연시켜 사용자 경험을 향상시켰다.

내 프로젝트에 적용

위의 글을 바탕으로 사용자의 프로필을 불러오는 로딩에 조건부 스켈레톤 로딩을 적용시켰다.
네트워크 텝에서 No throttling일 경우 평균적으로 86ms,Fast 4G 일 경우 186ms정도가 나오기 때문에 로딩 지연을 200ms로 지정해두었다.

현재 Suspense가 적용되지 않는 문제가 발생해 useQuery의 isLoading을 사용해 적용시켰다. 추후에 이 문제가 해결되면 Suspense 컴포넌트로 변경할 예정이다.

export const Profile = () => {
  const { email, name, profile, isLoading } = useUserQuery();
  const [showSkeleton, setShowSkeleton] = useState(false);

  useEffect(() => {
    if (isLoading) {
      const timer = setTimeout(() => setShowSkeleton(true), 200);
      return () => clearTimeout(timer);
    }

    setShowSkeleton(false);
  }, [isLoading]);

  return (
    <div className="flex min-h-53 w-full gap-8 p-16">
      {showSkeleton ? (
        <>
          <Skeleton className="size-37 rounded-8" />
          <div className="flex flex-col gap-8 py-4">
            <Skeleton className="h-12 w-30 rounded-12" />
            <Skeleton className="h-10 w-70 rounded-12" />
          </div>
        </>
      ) : (
        <>
          {!isLoading && (
            <Image
              src={profile}
              alt="profile picture"
              width={37}
              height={37}
              className="shrink-0 rounded-8"
              priority
            />
          )}
          <div className="flex w-full justify-between">
            <div>
              <p className="text-sm-medium">{name}</p>
              <p className="text-xs-medium">{email}</p>
            </div>
            <button className="text-xs-normal">로그아웃</button>
          </div>
        </>
      )}
    </div>
  );
};

useEffect 내부에서 setTimeout을 사용해 스켈레톤 로딩을 200ms 지연시켜서 스켈레톤 로딩을 적용시켰다.

No throttling

Fast 4G

관련 PR 주소
https://github.com/slid-todo/front/pull/130

결론

스켈레톤 로딩은 사용자가 콘텐츠의 구조를 미리 파악할 수 있도록 도와주고, 스피너보다 체감 대기 시간을 줄여 UX를 향상시키는 효과적인 방법이다.

그러나 모든 경우에 적합한 것은 아니며, 네트워크 응답 속도와 사용자 경험을 고려해 적절한 지연 시간을 설정하는 것이 중요하다. 카카오페이처럼 로딩 지연을 적용하면 불필요한 스켈레톤 표시를 줄이면서도 원활한 사용자 경험을 제공할 수 있다.

결과적으로 스켈레톤 로딩을 적절하게 활용하면 UX를 개선할 수 있지만, 적용 방식과 시점을 신중하게 고려해야 한다.

참고

헤이딜러 UX 스터디

카카오페이 기술 블로그

스켈레톤 로딩

profile
안녕하세요. 프론트엔드 개발 공부를 하고 있습니다.

0개의 댓글

관련 채용 정보