Layout Shift

GSJGSJ
1 min read

๐Ÿ’ฅ ๋ฌธ์ œ ์ •์˜

์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ ๊นœ๋ฐ•๊ฑฐ๋ฆผ์œผ๋กœ ์ธํ•ด 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-์ ์šฉํ•˜๊ธฐ

0
Subscribe to my newsletter

Read articles from GSJ directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

GSJ
GSJ