인프런 커뮤니티 질문&답변

챠챠_님의 프로필 이미지

작성한 질문수

Next + React Query로 SNS 서비스 만들기

Suspense로 Streaming하여 최적화하기(feat. loading.tsx, error.tsx)

api호출 3초뒤로 하고, loading.tsx 파일이 있을 때 없을때 /home/page.tsx

24.05.17 15:35 작성

·

127

0

안녕하세요 제로초님

제목처럼
api호출 3초뒤로 하고, loading.tsx 파일이 있을 때 없을때 /home/page.tsx

이런식으로 테스트를 해봤습니다.

 

/home/page.tsx에서는 react-query로 ssr을 적용했고

import style from './home.module.scss'
import Tab from "@/app/(afterLogin)/home/_component/Tab";
import TabProvider from "@/app/(afterLogin)/home/_component/TabProvider";
import PostForm from "@/app/(afterLogin)/home/_component/PostForm";
import { HydrationBoundary, QueryClient, dehydrate } from '@tanstack/react-query';
import TabDecider from "@/app/(afterLogin)/home/_component/TabDecider";
import { getPostRecommends } from '@/app/(afterLogin)/_lib/getPostRecommends';

export default async function Home() {
  const queryClient = new QueryClient();
  await queryClient.prefetchInfiniteQuery({
    queryKey: ['posts', 'recommends'],
    queryFn: getPostRecommends,
    initialPageParam: 0,
  });
  const dehydratedState = dehydrate(queryClient);

  return (
    <main className={style.main}>
      <HydrationBoundary state={dehydratedState}>
        <TabProvider>
          <Tab />
          <PostForm />
          <TabDecider />
        </TabProvider>
      </HydrationBoundary>
    </main>
  );
}

 

/mocks/handlers.tsx에서는 postRecommends를 가져오되 3초 delay를 줬습니다.

http.get('/api/postRecommends', async ({ request }) => {
    console.log('----------------------------------handlers /api/postRecommends');
    await delay(3000);
    const url = new URL(request.url);
    const cursor = parseInt(url.searchParams.get('cursor') as string) || 0;
    return HttpResponse.json(
      [
        {
          postId: cursor + 1,
          User: User[0],
          content: `${cursor + 1} ${faker.lorem.paragraph()}`,
          Images: [{ imageId: 1, link: faker.image.urlLoremFlickr({ category: 'animals' }) }],
          createdAt: generateDate(),
        },
        {
          postId: cursor + 2,
          User: User[0],
          content: `${cursor + 2} ${faker.lorem.paragraph()}`,
          Images: [
            { imageId: 1, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
            { imageId: 2, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
          ],
          createdAt: generateDate(),
        },
        {
          postId: cursor + 3,
          User: User[0],
          content: `${cursor + 3} ${faker.lorem.paragraph()}`,
          Images: [],
          createdAt: generateDate(),
        },
        {
          postId: cursor + 4,
          User: User[0],
          content: `${cursor + 4} ${faker.lorem.paragraph()}`,
          Images: [
            { imageId: 1, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
            { imageId: 2, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
            { imageId: 3, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
            { imageId: 4, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
          ],
          createdAt: generateDate(),
        },
        {
          postId: cursor + 5,
          User: User[0],
          content: `${cursor + 5} ${faker.lorem.paragraph()}`,
          Images: [
            { imageId: 1, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
            { imageId: 2, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
            { imageId: 3, link: faker.image.urlLoremFlickr({ category: 'animals' }) },
          ],
          createdAt: generateDate(),
        },
      ]
    );
  }),

 

 

이 후에 ssr화면 테스트를 위해서

브라우저의 자바스크립트 사용중지 했습니다.

서버도 각각 재시작하고 테스트했습니다.

그리고 나서 테스트한 화면입니다.

아래 화면은 loading.tsx가 업을때,

아래 화면은 loading.tsx가 있을때 입니다.

선생님 강의에서

ssr을 적용했을때 loading화면을 포기해야한다고 이해했었습니다.

prefetchInfiniteQuqery를 쓰고 loading을 포기하거나,

prefetchInfiniteQuqery을 포기하고 loading을 사용하거나.

그런데 제가 테스트했을때는 ssr이라도 로딩 화면이 보이는걸로 봐서 제가 테스트를 잘못한건지,

loading.tsx가 있는것 자체가 suspense를 사용한것과 동일한 효과를 주어서 보여지게 되는건지

여쭙고 싶습니다.

 

제가 잘못테스트했다면 어떻게 테스트를 해야 좀 더 정확히 구분지을 수있을지도 궁금합니다.

 

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2024. 05. 17. 16:19

지금 궁금한 게 혹시 tabDecider 안에 useSuspenseQuery를 사용하신 상태인가요? Suspense가 적용되어 있으면 react-query는 ssr을 하지 않습니다.

챠챠_님의 프로필 이미지
챠챠_
질문자

2024. 05. 17. 16:49

선생님 위 질문은 useSuspenseQuery를 사용하지 않은 상태에서 한 테스트입니다.

 

그래서

page.tsx 옆에 loading.tsx파일을 놓는것만으로 suspense가 적용되어있는 걸로 인식해서 그런건지 궁금했습니다.
혹은 제가 테스트를 잘못한건지 알고 싶었습니다.

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2024. 05. 18. 00:45

https://github.com/vercel/next.js/issues/50150

이거 이 이슈인 것 같은데요. loading.tsx가 js 끈 상태에서 있으면 렌더링 문제가있어보입니다. 혹시 js를 켜면 초기 렌더링이 어떤가요?

챠챠_님의 프로필 이미지
챠챠_
질문자

2024. 06. 02. 03:13

선생님 답변이 늦어서 죄송합니다.

loading.tsx파일이 있을때 js를 켰을때 미리보기


loading.tsx파일이 없을때 js를 켰을때 미리보기 입니다.

이걸로 미루어보아
loading.tsx파일이 존재하는것만으로 suspense적용하는걸로 인식해서 ssr을 못하는게 아닌가 추측해봤습니다.

suspense를 사용하면 특정 부분에 적용해주고, 그렇지 않고 loading.tsx만 있으면 전체를 suspense해주는게 아닌가 하는...
선생님이 답변해준 다른 질문들을 봤을때도 ssr작업을 했더라도 suspens를 사용하면 ssr 포기해야한다는 글을 봤어서 그렇게 생각했습니다.

 

그리고 문서를 봤을때 ssr을 다 포기하는건 아니고 정적인 부분(suspense를 감싸지 않은)부분은 ssr로 되고 데이터 호출해야 하는 부분은 안되는것 같습니다. 제가 이해한 부분이 맞는지 궁금합니다.

챠챠_님의 프로필 이미지

작성한 질문수

질문하기