개발자일기/리액트 이야기

스켈레톤 로딩(Skeleton Loading)을 구현해보자! (CSS, React)

뫙뭉 2024. 11. 7. 13:41
반응형

웹사이트나 애플리케이션에서 로딩 중인 페이지를 효과적으로 보여주는 방법 중 하나가 **스켈레톤 로딩(Skeleton Loading)**입니다. 스켈레톤 로딩은 실제 콘텐츠가 표시되기 전에, 콘텐츠가 배치될 위치에 미리 회색이나 반투명한 블록을 띄워 보여주는 방식으로, 사용자는 로딩을 기다리면서도 화면 구성을 미리 파악할 수 있습니다. 이번 글에서는 스켈레톤 로딩 애니메이션이 무엇인지, 그리고 CSS를 활용해 간단하게 구현하는 방법을 단계별로 설명해 보겠습니다.


 

스켈레톤 로딩이란?

 

스켈레톤 로딩은 웹이나 모바일 앱에서 콘텐츠가 로드될 위치에 기본적인 블록 형태를 미리 보여주는 방법입니다. 사용자는 콘텐츠가 나타날 위치를 미리 시각적으로 인지할 수 있기 때문에 로딩을 기다리는 동안의 불편함이 줄어들고, UX가 개선됩니다. 많은 서비스들이 이 방식을 사용하고 있으며, 특히 SNS 피드, 이미지 갤러리, 블로그 등 로딩 시간이 긴 페이지에서 효과적입니다.

스켈레톤 로딩의 장점

  • 사용자 경험 개선: 콘텐츠 로딩 동안 화면이 빈 상태로 남지 않아 사용자가 페이지가 로드되고 있다는 신호를 받을 수 있습니다.
  • 더 부드러운 전환: 콘텐츠가 로드되면서 갑자기 나타나는 대신, 스켈레톤이 자연스럽게 콘텐츠로 전환되어 더 부드러운 화면 전환이 가능합니다.

 


 

기본 CSS를 활용한 스켈레톤 로딩 구현하기

 

이제 CSS만으로 간단한 스켈레톤 로딩 애니메이션을 구현해 보겠습니다. 가로로 긴 블록과 작은 이미지 블록 형태의 스켈레톤을 만들어 텍스트와 이미지를 대신하는 기본적인 스켈레톤 구조를 만들겠습니다.

HTML 구조

<div class="skeleton-wrapper">
  <div class="skeleton-image"></div>
  <div class="skeleton-text"></div>
  <div class="skeleton-text"></div>
  <div class="skeleton-text short"></div>
</div>

 

CSS 스타일

 

스켈레톤 블록에는 연한 회색을 사용하여, 실제 콘텐츠가 아닌 임시 영역임을 표시합니다. CSS 애니메이션을 사용해 스켈레톤에 그라데이션 효과를 추가하여 생동감 있게 만들어 보겠습니다.

/* 기본 스타일 */
.skeleton-wrapper {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 300px;
  padding: 20px;
}

.skeleton-image {
  width: 100%;
  height: 180px;
  background: #e0e0e0;
  border-radius: 8px;
  animation: shimmer 1.5s infinite linear;
}

.skeleton-text {
  width: 100%;
  height: 20px;
  background: #e0e0e0;
  border-radius: 4px;
  animation: shimmer 1.5s infinite linear;
}

.skeleton-text.short {
  width: 60%;
}

/* 스켈레톤 애니메이션 */
@keyframes shimmer {
  0% {
    background-position: -100%;
  }
  100% {
    background-position: 100%;
  }
}

.skeleton-image,
.skeleton-text {
  background: linear-gradient(
    90deg,
    #e0e0e0 25%,
    #f5f5f5 50%,
    #e0e0e0 75%
  );
  background-size: 200% 100%;
}
 

CSS 설명

  • .skeleton-wrapper: 스켈레톤 로딩 블록을 감싸는 래퍼로, 각 스켈레톤 요소의 간격을 지정합니다.
  • .skeleton-image: 이미지를 대신하는 사각형 스켈레톤으로, 180px 높이에 둥근 모서리를 적용합니다.
  • .skeleton-text: 텍스트를 대신하는 사각형 스켈레톤으로, 폭은 100%이며 높이는 20px입니다.
  • 애니메이션 (shimmer): @keyframes shimmer를 통해 좌에서 우로 그라데이션 효과가 이동하는 애니메이션을 설정해 생동감을 줍니다.

이런거 많이 보셨죠? 트렌디하고 사용자 경험을 개선시켜줍니다

 

현재 간단한 예시 코드를 보여줬지만, 다양한 폼과 방식으로 해당 UX를 구현할 수 있습니다.

대표적인 예로 Pinterest같은 경우, 이미지 카드의 대표 색을 통해 형태와 어떤 이미지가 들어올지에 대한 것을 사용자가 미리 알 수 있는 UX를 제공했었습니다. (지금은 해당 UX를 채택하지 않고 있는 것 같네요.)

 


 

스켈레톤 로딩 애니메이션을 React와 함께 구현하기

 

실제 프로젝트에서 React와 함께 사용할 때는 로딩 상태를 기반으로 스켈레톤과 실제 콘텐츠를 전환하는 방식을 사용합니다.

React 예제 코드

아래는 로딩 상태가 활성화되면 스켈레톤을 보여주고, 로딩이 완료되면 실제 콘텐츠로 전환하는 React 코드입니다.

import React, { useState, useEffect } from 'react';
import './Skeleton.css';

const SkeletonLoadingExample = () => {
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const timer = setTimeout(() => {
      setIsLoading(false);
    }, 3000); // 3초 후 로딩 완료

    return () => clearTimeout(timer);
  }, []);

  return (
    <div>
      {isLoading ? (
        <div className="skeleton-wrapper">
          <div className="skeleton-image"></div>
          <div className="skeleton-text"></div>
          <div className="skeleton-text"></div>
          <div className="skeleton-text short"></div>
        </div>
      ) : (
        <div className="content">
          <img src="your-image-url.jpg" alt="Loaded content" />
          <h3>로딩 완료된 콘텐츠</h3>
          <p>이 텍스트는 로딩 후에 표시됩니다.</p>
        </div>
      )}
    </div>
  );
};

export default SkeletonLoadingExample;

 

  • useState와 useEffect를 사용해 로딩 상태(isLoading)를 관리합니다.
  • 3초 후 isLoading 상태가 false로 변경되며 실제 콘텐츠가 표시됩니다.
  • 로딩 상태가 true인 동안 스켈레톤 로딩 애니메이션이 보여지고, false가 되면 실제 콘텐츠로 전환됩니다.

 


 

스켈레톤 로딩, 항상 옳은 UX일까?

 

스켈레톤 로딩은 UX를 개선하기 위한 강력한 방법이지만, 모든 상황에서 적합한 것은 아닙니다. 경우에 따라서는 스켈레톤 로딩이 사용자에게 불필요한 로딩 시간을 느끼게 하거나 오히려 혼란을 줄 수 있습니다. 아래에서는 스켈레톤 로딩이 더 효과적인 상황과 그렇지 않은 상황을 설명하겠습니다.

스켈레톤 로딩이 더 적절한 상황

  1. 콘텐츠가 예측 가능하고 일관된 구조를 가질 때
    • 예를 들어, 피드 형식의 글 목록이나 상품 목록 페이지처럼 콘텐츠 구조가 일정할 때 스켈레톤 로딩은 적절합니다. 사용자는 로딩 중에도 스켈레톤의 형태를 통해 무엇이 나타날지 예상할 수 있기 때문에 유용하게 작동합니다.
  2. 짧은 시간 안에 콘텐츠가 로드될 때
    • 스켈레톤 로딩은 비교적 빠르게 로딩되는 콘텐츠에 적합합니다. 만약 콘텐츠 로딩 시간이 너무 길다면, 스켈레톤이 사용자의 기대감을 불필요하게 높일 수 있습니다. 1~2초 내에 콘텐츠가 표시될 때 스켈레톤이 좋은 효과를 발휘합니다.
  3. 콘텐츠의 순차적 로딩이 필요한 경우
    • 예를 들어, 대용량 이미지고해상도 영상처럼 순차적 로딩이 필요한 콘텐츠의 경우, 스켈레톤을 통해 로딩 중임을 명확히 보여줄 수 있습니다. 이렇게 하면 사용자가 페이지가 고장 난 것이 아니라, 로딩 중임을 이해할 수 있어 UX가 개선됩니다.

스켈레톤 로딩이 적합하지 않은 상황

  1. 구조가 복잡한 데이터
    • 스켈레톤 로딩은 예측 가능한 단순한 레이아웃에 유용하지만, 복잡한 데이터다양한 콘텐츠 타입이 섞여 있는 경우에는 오히려 스켈레톤이 사용자의 혼란을 초래할 수 있습니다.
  2. 긴 로딩 시간이 필요한 경우
    • 스켈레톤 로딩은 짧은 시간 내에 콘텐츠가 표시될 때 유용하지만, 데이터 로드 시간이 길다면 사용자는 오히려 스켈레톤을 보는 동안 지루함을 느낄 수 있습니다. 이 경우 프로그레스 바나 **스피너(spinner)**가 더 적합할 수 있습니다.
  3. 빠른 반응이 중요한 페이지
    • 일부 서비스에서는 즉각적인 반응이 필요한 경우도 있습니다. 예를 들어, 검색 결과 페이지에서는 스켈레톤 로딩보다는 검색어를 입력하는 즉시 부분적 결과를 보여주는 방식이 사용자에게 더 유용할 수 있습니다.

 


 

스켈레톤 로딩 외의 UX 개선을 위한 다른 UI 기법

 

스켈레톤 로딩 외에도 로딩 시간을 사용자에게 자연스럽게 알리고 불편함을 줄이는 다양한 UI 기법이 존재합니다. 상황에 따라 적절한 방법을 선택하여 사용할 수 있습니다.

  1. 프로그레스 바(Progress Bar)
    • 로딩이 진행되고 있는 상태를 시각적으로 퍼센트로 표시하는 방식입니다. 특히, 파일 업로드, 다운로드, 긴 데이터 처리와 같이 진행 상황이 예측 가능한 경우에 적합합니다. 예를 들어, 긴 업로드나 다운로드 작업에서 사용자에게 현재 얼마나 로드되었는지 알려주어 불확실성을 줄여줍니다.
  2. 스피너(Spinner) 또는 로딩 아이콘
    • 스피너는 로딩 중임을 직관적으로 나타내는 단순한 회전형 아이콘입니다. 주로 단시간의 로딩 상태를 표시할 때 사용되며, 사용자가 시스템이 작동 중임을 쉽게 인지할 수 있게 해 줍니다.
  3. 로딩 메시지와 재미있는 텍스트
    • 로딩 중인 상태를 재미있고 유머러스한 텍스트로 전달하는 방법입니다. 예를 들어, **"데이터를 불러오는 중입니다... 잠시만 기다려 주세요!"**라는 텍스트 대신, **"우주에서 데이터를 가져오는 중입니다!"**와 같은 문구를 사용하면 사용자에게 긍정적인 감정을 줄 수 있습니다.
  4. 페이드(Fade) 전환 효과
    • 로딩 완료 후 콘텐츠를 서서히 나타나게 하는 페이드 전환 효과는 사용자 경험을 부드럽게 만듭니다. 스켈레톤 로딩과 결합하면 자연스럽게 콘텐츠가 전환되며, 사용자가 페이지의 변화를 직관적으로 느낄 수 있습니다.
  5. 순차적 로딩(Lazy Loading)
    • 스크롤을 내릴 때마다 새로운 콘텐츠를 로딩하는 방식으로, 특히 긴 콘텐츠 피드에 적합합니다. 예를 들어, SNS나 뉴스 피드에서는 스크롤 내릴 때마다 새로운 콘텐츠를 불러오는 순차적 로딩 방식을 사용해 초기 로딩 시간을 줄이고 페이지 성능을 최적화할 수 있습니다.

위 예제를 통해 간단한 스켈레톤 로딩 애니메이션을 구현할 수 있습니다. 앞으로 로딩이 필요한 페이지나 컴포넌트에서 이 방식으로 사용자 경험을 높일 수 있는 멋진 스켈레톤 로딩을 시도해 보세요!

 

 
반응형