스켈레톤 컴포넌트는 데이터를 가져오는 동안 사용자가 로드 중인 상태를 시각적으로 알려주는 디자인 패턴이다. 이 방법은 데이터가 완전히 로드되기 전에 페이지의 레이아웃을 대략적인 형태로 보여준다. 이 형태는 일반적으로 회색 블록이나 줄들로 이루어져 있으며, 최종 컨텐츠가 들어갈 자리를 대략적으로 표현한다.
스켈레톤 UI의 주요 목적
로딩 인디케이터
페이지나 앱이 여전히 작동 중이고 데이터가 로딩되고 있다는 것을 사용자에게 알린다. 이는 단순히 로딩 스피너나 진행 바를 보여주는 것보다 사용자에게 더 많은 정보를 제공한다.
인지적 부하 감소
사용자가 최종 컨텐츠의 형태와 구조를 예상할 수 있게 하여, 실제 컨텐츠가 로드될 때 정보를 더 빠르게 처리할 수 있도록 돕는다.
보다 나은 사용자 경험
빈 화면 대신 구조화된 플레이스홀더를 보여주어 사용자의 인내심을 돕고, 페이지가 로드되는 동안의 불편함을 줄여준다.
스켈레톤 UI 는 데이터 로딩 시간이 긴 웹 애플리케이션, 특히 복잡한 데이터와 인터랙션이 많은 대시보드, 피드, 또는 목록이 있는 경우에 특히 유용하다. 이 패턴은 사용자에게 페이지 로딩 중인 상태를 더 명확하게 전달하고, 컨텐츠가 곧 등장할 것임을 암시하여 사용자의 관심을 유지하는 데 도움을 준다.
tailwind 에는 따로 스켈레톤을 위한 유틸리티 css 가 없으니 직접 만들어 써야한다.
따라서 tailwind.confing.js
에 다음과 같은 코드를 추가해줘야한다.
// tailwind.config.js
extend: {
animation: {
shimmer: 'shimmer 1.5s infinite linear',
},
keyframes: {
shimmer: {
'0%': { backgroundPosition: '200%' },
'100%': { backgroundPosition: '-200%' },
},
},
backgroundImage: {
'gradient-custom': 'linear-gradient(to right, #D9D9D9 0%, #EDEEF1 50%, #D9D9D9 100%)',
},
backgroundSize: {
custom: '300% 100%',
},
}
애니메이션은 본인 입맛대로 수정 및 작성해주면 된다.
그리고 이대로 쓸 수 있지만 여러곳에서 쓰일 것을 대비해 utility css
로 등록해둔다.
// index.css
@layer components {
.skeleton {
@apply animate-shimmer bg-gradient-custom bg-custom;
}
}
utility css
로 등록을 한 다음, 다음과 같이 작성하면 된다.
// Skeleton.tsx
export default function SkeletonLargeCard() {
return (
<div className="h-max overflow-hidden p-14pxr bg-white max-w-430pxr shrink-0 shadow-default">
<div className="flex justify-between min-h-54pxr items-center">
<div className="flex gap-4pxr items-center">
<div className="size-30pxr bg-gray_400 rounded-[30px] skeleton" />
<div className="w-60pxr h-25pxr bg-gray_400 rounded-[5px] skeleton" />
</div>
<div className="w-30pxr h-25pxr bg-gray_400 rounded-[5px] skeleton" />
</div>
<div className="w-full h-181pxr bg-gray_400 rounded-[5px] mb-20pxr skeleton" />
<div className="flex gap-5pxr mb-20pxr">
<div className="w-50pxr h-25pxr bg-gray_400 rounded-[5px] skeleton" />
<div className="w-50pxr h-25pxr bg-gray_400 rounded-[5px] skeleton" />
</div>
<div className="w-170pxr h-25pxr bg-gray_400 rounded-[5px] mb-10pxr skeleton" />
<div className="w-full h-25pxr bg-gray_400 rounded-[5px] skeleton" />
<div className="flex px-2pxr pt-20pxr pb-36pxr gap-4pxr items-center">
<div className="w-50pxr h-20pxr bg-gray_400 rounded-[5px] skeleton" />
<div className="w-50pxr h-20pxr bg-gray_400 rounded-[5px] skeleton" />
</div>
</div>
);
}
뼈대를 만든 다음 skeleton
tailwind css 를 추가해주면 된다.
그리고 로딩 상태일 때 Skeleton
을 불러오면 다음과 같이 애니메이션이 작동한다.
스켈레톤 을 적용하기 전에는 로고만 뚜둥 하고 뜨는 정도였다. 그마저도, 1초도 안되는 짧은 시간이었다. 네트워크를 통해 로딩속도를 조절하면 로고가 뜨고 빈 화면이 몇초간 유지가 되었다.
하지만, 스켈레톤 을 적용하였더니 일단 다음과 같은 장점을 느낄 수가 있었다.
로딩중
일단, 데이터가 로딩중 이라는 것을 로고만 뜨는 것보다 확실히 알 수가 있었다. 더구나, 그냥 회색 스켈레톤 만 띄우면 잘 알 수가 없을것이다. 하지만, 하얀 빛이 오른쪽으로 이동하고 있는 것을 통해 로딩중
이라는 것을 확실히 알 수 있었다.
앞으로의 레이아웃
레이아웃이 예상이 된다. 이 점이 생각보다 꽤 큰 도움이 되는 것 같다. 레이아웃을 미리 볼 수 있음으로써 정보들의 배치 혹은 내가 원하는 정보의 위치를 예상할 수 있었다. 스켈레톤 골격 자체가 데이터가 생기고 난 후의 골격을 따라가다보니 배치에서의 큰 오차가 없었다.