스켈레톤 화면으로 유저 이탈 방지하기

유소정·2024년 5월 21일
0
post-thumbnail

🙋 이 문서를 보고 나면

  • 유저 이탈 방지를 위한 방법으로 로딩 화면을 고려할 수 있다.
  • 사용자 경험에 도움이 되는 로딩 화면을 알 수 있다.
  • 스켈레톤 로딩을 구현할 수 있다.

📝 로딩 표시가 필요한 이유

Vercel에 따르면, 저희 애플리케이션은 화면을 처음 그리는데 평균 1.6초가 걸리고, 완벽하게 그리는데 평균 1.72초가 걸립니다.

1초만에 표시가 된다니, 굉장히 빠른 속도 같습니다.
하지만 로딩 표시가 없으면 1초도 사람에 따라 느리게 느껴지기도 합니다.

"무슨 상황이지?"라는 의문이 들며 막연하게 기다려야 되기 때문입니다.

그래서 이런 상황을 도와주는 것이 로딩 표시입니다.
로딩 표시는 예측을 도와줍니다.

그래서 실제로 세계적인 UX 리서치 그룹 닐슨 노먼은 로딩 표시에 대한 중요성을 강조하는데요, 약 1초 이상 걸리는 작업에는 로딩 표시를 사용하라는 말을 했습니다.

그래서 1초 이상의 로딩이 있는 저희 서비스에
답답함을 느끼지 않도록 로딩 표시를 넣게 되었습니다.

📝 스켈레톤 로딩을 선택한 이유

도입을 고려했던 로딩 표시는 3가지입니다.

  • 스피너 로딩: 아주 짧은 로딩
  • 스켈레톤 로딩: 너무 짧지도 길지도 않은 로딩
  • 프로그래스 바 로딩: 프로그램 다운처럼 긴 로딩

저는 이 중에서 스켈레톤 로딩을 선택했습니다.

스켈레톤 로딩이 너무 짧지도 길지도 않은 로딩에 적절한 이유는 '대기 시간'이 아닌 다음에 표시할 '진행 상황'에 초점을 맞추기 때문입니다.

그래서 저희 애플리케이션에는 스켈레톤 로딩을 도입했을 때,
체감상 대기 시간이 가장 짧다고 느꼈습니다.

로딩 시간이 너무 빠르면 스켈레톤 화면을 보여줄 시간이 없기 때문에
스켈레톤 화면이 지저분하게 느껴질텐데 저희 서비스는 그 정도로 빠르진 않았습니다.

📝 스켈레톤 로딩 구현하기

스켈레톤은 보여질 화면을 예측할 수 있도록 합니다.

그래서 구현은 보여질 화면의 코드에서 데이터 부분만 빼서 이용하면 됩니다.

저는 src/components/Loading 폴더에 스켈레톤에 대한 파일을 모아놓았습니다.

📦 스켈레톤 박스 구현하기

// Loading/Skeleton.tsx

import { styled } from 'styled-components';

type SkeletonBoxProps = {
  $width: number;
  $height: number;
  $radius: number;
}

const Skeleton = {
  SkeletonBox: styled.div<SkeletonBoxProps>`
    position: relative;
    overflow: hidden;
    background-color: ${(props) => props.theme.colors.skeletonBackground};
    width: ${(props) => props.$width}px;
    height: ${(props) => props.$height}px;
    border-radius: ${(props) => props.$radius}px;
    animation: 1s linear infinite alternate slidein;

    @keyframes slidein {
      50% {
        background-color: #dbdbdb;

      }
      100% {
        background-color: #bcbcbc;
      }
    }
`,
};

export default Skeleton;

📦 스켈레톤 박스 사용하기

// Loading/SkeletonFestivalLineupItem

import { styled } from 'styled-components';

import { SwiperSlide } from 'swiper/react';

import Skeleton from './Skeleton';

const SkeletonImg = styled(Skeleton.SkeletonBox)`
    box-shadow: 0px 2px 20px 0px rgba(0, 71, 201, 0.15);
`;

const Container = styled.div`
    height: 21rem;
    position: relative;
    padding-inline: 1.6rem;
    margin-bottom: 20px;
`;

export default function SkeletonFestivalLineupItem() {
  return (
    new Array(5).fill(1).map((_, i) => (
      <SwiperSlide key={i}>
        <Container>
          <SkeletonImg
            $width={200}
            $height={210}
            $radius={9}
          />
        </Container>
      </SwiperSlide>
    )));
}

📘 정리

애플리케이션 환경에 맞는 로딩으로 스켈레톤을 선택했습니다.

로딩 표시를 통해 유저에게 상황을 설명함으로써 이탈 방지를 할 수 있었습니다.

🔗 참고 링크

profile
기술을 위한 기술이 되지 않도록!

0개의 댓글