이미지 로딩 경험 개선하기 2 (feat. suspense)

스탁벅스·2023년 7월 31일
14
post-thumbnail
post-custom-banner

이전글에서 이미지의 onLoad 속성을 활용해 이미지가 모두 로딩될 때까지 skeleton ui를 보여주도록 구현했다.
프로젝트 진행을 하면서 tanstack query를 도입하게 됐는데, 이번에는 useQuery의 suspense 옵션을 활용해 문제를 해결해보았다.

문제 상황

한 페이지에 무한스크롤을 이용해 16개씩, 굉장히 무거운 고화질의 포스터들을 로딩하고 있다. 이미지 마다 용량이 다르고 로딩속도가 다르다 보니 보다시피 차마 눈뜨고 보기 힘든 ux를 경험했다.

useQuery + suspense

많은 경우 useQuery 훅을 단순히 서버의 데이터를 fetch해오는 경우 사용한다. 여기에 suspense 옵션을 true로 설정할 경우, 서버의 데이터가 성공적으로 fetch 될 때까지 화면에 등장하는 것을 미루고, fallback 컴포넌트를 대체해서 보여준다.
아래 코드는 그 예시다.

이미지 로딩에도 suspense 적용하기

하지만 사실 서버 데이터를 fetch해오는 경우에만 useQuery를 사용할 수 있는 것은 아니다. 공식문서에는 useQuery의 queryFn에 대해서,

Must return a promise that will either resolve data or throw an error

라고 설명한다. 즉, queryFn에는 그냥 프라미스가 들어가면 된다.

이미지의 로딩 완료시 resolve 되는 Promise를 만들자.

loadImage 함수는 이미지 로딩완료시 이미지의 주소를 리턴하게 된다.

loadImage를 useQuery의 queryFn으로 넣어주고, suspense 옵션을 true로 설정해준다.

결과로 리턴되는 이미지 주소를 Poster 컴포넌트에 넘겨주었다.

그리고 16개의 포스터들을 담고있는 컴포넌트를 Suspense로 감싸주고 fallback으로 skeleton ui를 담고있는 Loading 컴포넌트를 넣어준다.

결과

훨씬 더 개선된 로딩경험을 확인 할 수 있다.

profile
환영합니다. 스탁벅스입니다.
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 7월 31일

좋은 글 감사합니다. 자주 올게요 :)

답글 달기