이번 프로젝트에서는 서버 데이터 관리에 리액트 쿼리를 사용했다. 리액트 쿼리를 사용하면 쉽게 로딩 처리를 해줄 수 있다. 이전 포스팅에서도 알 수 있듯이, 로딩 상태일 때 좋은 사용자 경험을 위해 로딩 스피너 라이브러리를 사용했었다.
페이지가 렌더링 될 때 하나의 컴포넌트(특정 부분)에서만 로딩 스피너가 뜨면 큰 상관이 없겠지만 메인 페이지가 렌더링 될 때 게시글 캐러셀 컴포넌트와 채팅방 리스트 컴포넌트 총 두 개의 컴포넌트가 보이고 두 컴포넌트 모두 서버에서 데이터를 가져오며 로딩 스피너가 뜨니 난잡한 느낌이 들었다.
내가 맡은 게시글 파트만 구현할 때는 몰랐었는데 팀원 분이 맡으신 채팅 파트에 리액트 쿼리를 적용하고 똑같이 로딩 스피너가 뜨도록 해주니 두 개의 로딩 스피너가 각기 다른 속도로 사라지니 영 마음에 들지 않았다.
그래서 리팩토링을 결심했다!
프로젝트 종료 몇 일 남지도 않은 그 상황에서..하하.. 어쩌겠어.. 이번 프로젝트는 정말 디자인 적으로 귀여운 느낌과 동시에 깔끔한 느낌을 가져가고 싶었다.
스켈레톤 UI는 다음 이미지와 같이 로딩 중에 사용자에게 문제가 있는 것이 아니라 로딩 중이니 불안해하지마세요! 라는 느낌을 주는 UI이다. 나는 유튜브를 통해 알게되었다!
이번 프로젝트에서는 공통 컴포넌트를 통해 겹치는 코드를 줄이기 위해 노력했었다. 스켈레톤 UI도 마찬가지로 공통 컴포넌트로 만들었다.
이것은 메인 컴포넌트에 있는 캐러셀 컴포넌트를 위한 스켈레톤 UI 이다. 이것 말고도 마이페이지용, 리스트 아이템 용 스켈레톤 UI를 공통 컴포넌트로 만들어 사용했다.
import styled, { keyframes } from 'styled-components';
const loadingAnimation = keyframes`
0% {
background-position: -200px 0;
}
100% {
background-position: calc(200px + 100%) 0;
}
`;
const SkeletonCarouselWrapper = styled.article`
width: calc(90%);
height: 100%;
`;
const SkeletonTagWrapper = styled.section`
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
margin: 30px 0px 20px 0px;
p {
margin: 0px 0px 0px 10px;
font-size: x-large;
font-weight: 700;
}
button {
background-color: transparent;
border: none;
margin: 0px 1px 0px 0px;
font-size: medium;
font-weight: 600;
cursor: pointer;
&:hover {
color: #c7d36f;
}
}
`;
const SkeletonItem = styled.div`
width: 70%;
height: 40px;
background: linear-gradient(
90deg,
rgba(200, 200, 200, 0.4) 25%,
rgba(220, 220, 220, 0.5) 37%,
rgba(200, 200, 200, 0.4) 63%
);
background-size: 200px;
animation: ${loadingAnimation} 1.8s infinite;
margin: 6px;
padding: 6px;
border-radius: 20px;
cursor: pointer;
display: flex;
align-items: center;
`;
const SkeletonSliderItem = styled.div`
width: 100%;
max-width: 800px;
height: 110px;
background: linear-gradient(
90deg,
rgba(200, 200, 200, 0.4) 25%,
rgba(220, 220, 220, 0.5) 37%,
rgba(200, 200, 200, 0.4) 63%
);
background-size: 200px;
animation: ${loadingAnimation} 1.8s infinite;
border-radius: 20px;
margin: 20px 0px 20px 0px;
`;
export const SkeletonCarousel = () => (
<SkeletonCarouselWrapper>
<SkeletonTagWrapper>
<SkeletonItem style={{ width: '50%', height: '30px' }} />
<SkeletonItem style={{ width: '10%', height: '25px' }} />
</SkeletonTagWrapper>
<>
<SkeletonSliderItem />
<SkeletonSliderItem />
<SkeletonSliderItem />
</>
</SkeletonCarouselWrapper>
);
로딩 스피너 자리에 적용해주면 다음과 같이 애니메이션 효과까지 더해진 스켈레톤 UI를 볼 수 있다. 개인적으로는 로딩 스피너보다 훨씬 세련되어 보이는 것 같다.
앞으로도 로딩 처리에는 스켈레톤 UI를 사용할 것 같다. 만족!
'프로젝트 > 나무(나누고 나눔받는 무한 지식 품앗이)' 카테고리의 다른 글
모달 / 스켈레톤 UI 디자인 리팩토링 (0) | 2023.08.12 |
---|---|
[회고] 프론트엔드 2인 팀 프로젝트 '나무' 회고 (0) | 2023.07.30 |
[React] React tooltip 간단하게 적용하기(hover 시 부가 설명) (0) | 2023.07.26 |
[React & React-Query] 가만히 있어도 데이터 실시간 업데이트 되도록 하기 (0) | 2023.07.26 |
[React & Recoil] a태그로 인한 새로 고침 + 새로 고침 시 리코일 전역 데이터 날라가는 현상 (0) | 2023.07.25 |