비동기적 데이터를 가져오는 로딩시간 동안 사용자들은 멍하니 기다려야 한다. 이에 대한 더 나은 사용자 경험을 제공하기 위한 방법은 두가지가 있다.
- 절대적인 로딩 시간을 줄이기
- 로딩 체감 시간을 줄이기
이 포스트에서는 두번째 방법을 달성하기 위해 사용하는 Skeleton에 대해 다뤄보려한다.
로딩 상태를 다루는 방식엔 크게 세가지가 있다.
- Skeleton
- Custom-Loading-Animation, Spinner, Progress-Bar
- Blank (빈 화면)
각 방식 별 로딩 체감을 비교한 연구자료에 따르면,
사용자들은 Skeleton 방식을 사용했을때
Blank 보다 약 0.4~ 0.75초,
Spinner 보다 약 0.04초~ 0.16초 가량 로딩을 짧게 느꼈다고 한다.
YouTube
YouTube는 썸네일, 아바타, 영상 세부 정보 및 NavBar에 대한 정보를 가져오는 동안 Skeleton을 사용하여 로딩 체감시간을 줄여준다.전체적인 UI의 큰 변화는 느껴지지 않지만 우측 상단 NavBar의 UI가 정확히 일치하지 않고 살짝 움직이는 것이 느껴진다.
인스타그램
인스타그램 역시 비슷한 방식으로 Skeleton을 사용한다. YouTube와는 달리 상단 NavBar의 프로필 아이콘을 제외한 아이콘들은 먼저 표현된다. 로딩 이전과 이후의 UI가 완전히 일치하기 때문에 YouTube에 비해 한층 더 안정감 있게 느껴진다.
포스트 디테일을 불러오는 동안에는 Skeleton의 Animation 효과를 주고 있다.
효과적 Skeleton Animation 대한 연구에 따르면,
1. Animation이 오른쪽으로 흐를때
2. Pulse(Fade-in ,Fade-Out)보다 Wave나 Shimmer를 사용했을때
3. 지속적으로 천천히 움직일때
로딩 체감을 줄이는데 효과적이었다고 한다.
npm install antd
@import "~antd/dist/antd.css";
import React, { useEffect, useState } from "react";
import { Skeleton, List, Avatar } from "antd";
//Antd UI Component인 List와 Avatar를 추가로 활용했다.
import "./App.css";
function App() {
const [isloading, setIsLoading] = useState(true);
const listData = [];
for (let i = 1; i < 6; i++) {
listData.push({
title: `User ${i}`,
avatar: ⋯
content:
"동해물과 백두산이 ⋯",
});
}
useEffect(() => {
const timer = setTimeout(() => {
setIsLoading(false);
}, 2000);
return () => clearTimeout(timer);
}, []); // 2초 후 로딩완료
return (
<div className="App">
<List
itemLayout="vertical"
size="large"
dataSource={listData}
renderItem={(item) => (
<List.Item key={item.title}>
<Skeleton
loading={isLoading}
active
avatar
title={{ width: "100px" }}
paragraph={{ width: "400px", rows: 1}}
>
<List.Item.Meta
avatar={<Avatar src={item.avatar} />}
title={<a href={item.href}>{item.title}</a>
/>
{item.content}
</Skeleton>
</List.Item>
)}
/>
</div>
);
}
export default App;
<List/>
의 <List.Item/>
각각을 <Skeleton/>
으로 감싸준다.
<Skeleton/>
에 avatar
, title
,paragraph
props를 사용해 Skeleton UI를 만든다.
useState
와 useEffect
를 사용해 일정 시간 후 isLoading
이 false
가 되게한다.
<Skeleton/>
에 loading
props를 사용해isLoading
이 true
일때만 표현되게 설정한다.
active
props를 통해 애니메이션 효과를 준다.
Skeleton을 이용하면 어렵지 않은 방법으로 비동기 작업을 처리하는동안 사용자 로딩체감시간을 줄여줌으로써 더나은 사용자경험을 제공할 수 있다.