Layout Shift

๐ฅ ๋ฌธ์ ์ ์
์ด๊ธฐ ๋ ๋๋ง ์ ๊น๋ฐ๊ฑฐ๋ฆผ์ผ๋ก ์ธํด UI ์์๋ค์ด ์ด๋๋์ด UX๊ฐ ์ ํ๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๐ ์์ธ ๋ถ์
์์ธ ํ์ด์ง์์ ์ฐธ์ฌ์ ๋ชฉ๋ก ๋ฐ์ดํฐ๋ฅผ ํด๋ผ์ด์ธํธ์์ API ์์ฒญ์ผ๋ก ๊ฐ์ ธ์ค๋๋ก ๊ตฌํ๋์ด ์์์ต๋๋ค. ๋ฐ์ดํฐ๊ฐ ๋์ฐฉํ๊ธฐ ์ ์ ํด๋น ์์ญ์ ๋น์ด์๋ ์ํ๋ก ๋ ๋๋ง๋์๊ณ , ๋ฐ์ดํฐ๊ฐ ๋์ฐฉํ ํ์์ผ ์ฑ์์ง๋ฉด์ ํ๋ฉด์ด ์ ๊น ๊น๋นก์ด๋ ํ์์ด ๋ฐ์ํ์ต๋๋ค.
๐ง ํด๊ฒฐ๋ฐฉ๋ฒ
์๋ฒ ์ปดํฌ๋ํธ๋ฅผ ํ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ์ ธ์์ ์บ์ฑํ ๋ค, ํด๋ผ์ด์ธํธ์์๋ ์บ์ฑ๋ ๋ฐ์ดํฐ๋ฅผ ์ฆ์ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
์ด๋ฅผ ์ํด Tanstack Query์ prefetchQuery์ dehydrate๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
prefetchQuery
์ ๋ฏธ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ ์บ์์ ์ ์ฅํด useQuery์์ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
dehydrate
์ ์๋ฒ์์ ๋ฏธ๋ฆฌ ๊ฐ์ ธ์จ ์ฟผ๋ฆฌ๋ฅผ ํด๋ผ์ด์ธํธ์์ ํ์ฉํ ์ ์๋๋ก ํด์ค๋๋ค.
// ์๋ฒ ์ปดํฌ๋ํธ์์ QueryClient ์์ฑ
const queryClient = getQueryClient();
// ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ์ ธ์ ์บ์ฑ
await Promise.all([
queryClient.prefetchQuery({
queryKey: QUERY_KEYS.participants(gatheringId),
queryFn:() => getParticipants(gatheringId),
}),
...
// ์๋ฒ์์ ์บ์๋ ๋ฐ์ดํฐ๋ฅผ ํด๋ผ์ด์ธํธ๋ก ์ ๋ฌ
const dehydratedState = dehydrate(queryClient);
...
// HydrationBoundary๋ก ๊ฐ์ธ state ์ ๋ฌ
<HydrationBoundary state={dehydratedState}>
<Gathering />
</HydrationBoundary>
๐ก ๊ฒฐ๊ณผ
์๋ฒ ์ปดํฌ๋ํธ์์ ์ฟผ๋ฆฌ๋ฅผ ์บ์ฑํ์ฌ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ ๋ถํ์ํ API ์์ฒญ ๊ฐ์ํ์์ต๋๋ค.
์๋ก๊ณ ์นจ ์์๋ UI shift๋ฅผ ๋ฐฉ์งํ์ฌ ์์ ์ ์ธ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ์์ต๋๋ค.
๐ ๋ฐฐ์ด ์
Tanstack Query์์ prefetchQuery์ dehydrate์ ์๋ก ์๊ฒ๋์์ต๋๋ค.
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์์ ๋ ๋์ ์ด๊ธฐ ๋ก๋ฉ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ ์ ์๋ค๋ ์ ์ ํ์ตํ์ต๋๋ค.
๐๏ธ ์ฐธ๊ณ
https://tanstack.com/query/latest/docs/framework/react/reference/hydration#dehydrate
https://tanstack.com/query/latest/docs/reference/QueryClient#queryclientprefetchquery
https://velog.io/@day_1226/Next.js-tanstack-query๋ก-prefetch-์ ์ฉํ๊ธฐ
Subscribe to my newsletter
Read articles from GSJ directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
