패스트캠퍼스 데브캠프

토이 3 프로젝트 작성한 코드 복기 (7) - Skeleton

vitamin3000 2025. 1. 19. 21:59

 

유튜브 앱을 사용할 때, 아직 동영상에 대한 정보를 받아오지 못했을 때 출력되는 흰색 컴포넌트들을 본적 있을 것이다.

 

이러한 흰색 컴포넌트를 skeleton이라하고, 이번 프로젝트에서 구현한 아래와 같은 skeleton을 만들어보자

 

1. skeleton 정의하기

우선 아래와 같이, tailwind-css 문법을 사용하여 만들 수 있다.

const MusicItemSkeleton = () => {
  return (
    <div className="h-[45vh] w-full animate-pulse rounded-md">
      <div className="flex">
        <div className="h-20 w-40 rounded-md bg-gray-200" />
        <div className="flex flex-col">
          <div className="ml-4 h-8 w-48 rounded-md bg-gray-200" />
          <div className="mt-1 flex items-center">
            <div className="ml-4 h-11 w-11 rounded-full bg-gray-200" />
            <div className="ml-1 h-8 w-36 rounded-md bg-gray-200" />
          </div>
        </div>
      </div>

 

이때 animate-pulse 옵션을 사용한 것을 볼 수 있다.

이것은 Tailwind CSS에서 제공하는 유틸리티 클래스 중 하나로, 요소에 애니메이션 효과를 추가하여 부드럽게 깜빡이 애니메이션처럼 보여지게 해준다.

최상위 부모 클래스에 추가해주면 된다.

 

2. skeleton 사용하기

 

이제 해당 페이지에서 사용하는 skeleton을 데이터를 불러오는 도중에 사용하면 된다.

 

  const { videoQuery } = useVideos({ videoId: video });

  const videoData = videoQuery.data;
  const { userQuery } = useUsers(videoData?.user_id);

  if (videoQuery.isLoading || userQuery.isLoading) {
    return <MusicItemSkeleton />;
  }

 

위 코드와 같이 isLoading중에 사용하면 된다.

 

3. 주의사항!

 

 

위 화면과 같이

1. 나의 북마크 목록, 북마크 카테고리 처럼 하나의 화면에 두 개의 컴포넌트가 존재할 때

2. 부모 컴포넌트인 BookmarkPage.tsx에서 myBookmarkList와 BookmarkCategory를 자식 컴포넌트로 내려줄 것인데,

3. 이 과정에서 부모 컴포넌트인 BookmarkPage에서 데이터를 받아서 isLoading에 대한 skeleton을 적용하고 값을  "내려" myBookmarkList와 BookmarkCategory에서는 사용만 하면 상관 없지만,

4. 만약 이 데이터 값의 userId나 videoId같이 key를 가지고 다른 table의 값을 참조하여 받아오는 경우에도 isLoading시에 skeleton이나 데이터가 비었을 때의 나타내는 컴포넌트를 적용하게 되면

5. 중복현상으로 여러개의 컴포넌트들이 짧은 시간안에 차례대로 렌더링되게 된다

6. 따라서 최하단의 자식 컴포넌트에서만 isLoading에 관한 skeleton을 처리하면 된다

 

4. skeleton은 언제 사용하는가?

웹/앱 사용자가 화면을 클릭했을 때의 결과물이 1.5초 이후부터 1초가 지날 때 마다 15%(?)씩 감소한다고 알고 있다.

따라서 하나의 페이지에 많은 컴포넌트를 렌더링하거나 속도가 느려 보여지는 시간이 느려진다면 사용자는 우리가 구현한 웹/앱 서비스를 사용하지 않을 것이다.

이때 곧 너가 원하는 것들이 화면에 나타날 거니 기다려를 나타내는 로딩 화면 또는 skeleton을 보여줄 것인데,

이때 로딩화면과 skeleton의 차이점에 대해 알고 어떤 것을 적용하면 좋을지 생각해보면 좋을 것 같다.

 

로딩 화면은 데이터가 로드되고 있다는 것을 강조하는 데 중점을 두고, 스켈레톤은 콘텐츠의 레이아웃을 미리 보여주어 사용자에게 더 나은 경험을 제공함에 중점을 두고 있다.