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

kraf님의 프로필 이미지
kraf

작성한 질문수

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

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

Next 기본 내장 loading.tsx 의 기능에 대한 질문이 있습니다!

해결된 질문

작성

·

720

·

수정됨

0

안녕하세요!

'Suspense로 Streaming하여 최적화하기(feat. loading.tsx, error.tsx)' 강의를 듣던 도중 갑자기 궁금한 것들이 생겨서 이렇게 질문드립니다!

 

  1.  

“ /home은 서버컴포넌트여서 서버에서 다 그려서 보내주기 때문에초기 로딩 자체가 존재하지 않는다. 그러므로 /home에서 새로고침을 해도 loading.tsx 가 적용되지 않는다

그렇지만 /explore에서 ‘새로고침 하고’ /home이라는 페이지로 넘어가면 /explore에서 /home페이지를 새로 로딩한다. 그래서 loading.tsx 가 적용된다 ”

라고 말씀하셨는데 여기서

‘/explore에서 새로고침을 하고난 다음에 /home페이지로 가면 해당 페이지를 새로 로딩한다’ 는 개념이 무슨 말씀이신가요? 이와 관련된 Next.js 의 개념 키워드가 있을까요?

 

 

 

  1.  

첫 페이지를 로딩 할 때 서버에서 미리 로딩된 것을 불러오기 때문에 Next에서 구성해주는 loading.tsx나, 리액트 쿼리에서 사용하는 isPending둘 다 의미가 없다. Next에서 첫 페이지의 데이터는 서버에서 전부 로딩하고 이걸 가져다 쓰기 때문이다

라고 하셨는데 여기서 첫 페이지가 정확히 무엇을 의미하는 것인가요?

최초 렌더링인지, 새로고침 이후 접근하는 페이지인지, 아니면 다른 페이지를 갔다가 그대로 다시 돌아오면 그것도 첫페이지가 되는 것인지 헷갈립니다ㅠㅠ

 

 

 

  1.  

(Next의 Streaming with Suspense 를 사용하기 전 내용입니다)

 

API에 await delay(3000) 를 사용했을 때,

prefetchInfiniteQuery를 사용한 PostRecommends.tsx 에서는

리액트 쿼리의 isPending은 적용되지 않지만, loading.tsx로 지정한 로딩 스피너는 보여집니다.

loading.tsx로 지정한 로딩 스피너가 보여질 때, 어쨌든 prefetchInfiniteQuery 를 통해 서버측에서 미리 데이터를

fetch할 때 API를 사용할텐데 이 때 API에 await delay(3000)가 있음에도

loading.tsx는 항상 await delay(3000)와 관계없이 아주 짧은 시간동안만 (거의 0.5초?) 나타나는데 이는 왜 그런가요?

최소 이 때 역시 API 호출로 인해 delay(3000)가 작동되면 3초 이상이 걸려야하는게 맞지 않나요?

이는 혹시 prefetchInfiniteQuery가 컴포넌트가 마운트 되기 전에 미리

데이터를 받아놓기 때문에 dealy(3000)이 직접적으로 체감되지 않기 때문인가요?

답변 2

1

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

  1. 새로고침하라는 의미는 왼쪽의 explore만 누르는 건 아무 의미가 없기 때문입니다. 왼쪽 explore 메뉴를 누르는 건 클라이언트 라우팅이고, 새로고침을 하는 행동은 서버 라우팅입니다. 즉, 서버 라우팅임을 확실히 하기 위해 새로고침을 하라는 겁니다.

  2. 최초 렌더링도 맞고, 새로고침 이후 접근하는 페이지도 맞습니다. 다른 페이지로 가는 메뉴를 누르는 건 아닙니다. "서버 라우팅"을 의미하는 겁니다.

  3. api postRecommends 데이터가 캐싱돼서 그렇습니다. 넥스트 서버를 껐다 켜면 캐시가 날아가서 다시 3초 기다립니다.

kraf님의 프로필 이미지
kraf
질문자

감사합니다!

결국 서버 라우팅이 적용되는 경우에 loading.tsx 가 적용되는 것으로 이해했습니다.

저는 Next.js의 서버컴포넌트에서 서버 라우팅이 발생하면 서버에서도 새로 fetch를 진행하고 새로운 HTML파일을 클라이언트로 보내는 것으로 알고 있습니다.

근데, 강의처럼 /explore URL에서 새로고침하고 /home URL로 이동하는 형태가 아니라

/home URL에서 계속 새로고침을 하는 행위 역시 서버 라우팅이 적용되는 상황으로 알고 있는데, 이때 loading.tsx가 전혀 적용되지 않는 이유는 무엇인가요?

 

강사님께서는 "home\page.tsx는 서버컴포넌트이므로 이 페이지를 서버에서 미리 그려서 보내주기 때문에 애초에 로딩이 필요가 없다." 라고 말씀을 하시긴 했는데 이 부분과 서버 라우팅의 개념이 헷갈리네요ㅠ

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

네? 서버 라우팅 때는 loading.tsx 적용 안 되고, 클라이언트 라우팅때만 적용되는 겁니다. 좌측 메뉴 누르는게 클라이언트 라우팅이고 이 때만 로딩창 뜹니다.

/explore에서 새로고침을 하라는 건 /home -> /explore -> /home으로 이동하게 되면 홈이 이미 캐싱되어있으므로 클라이언트 라우팅인데도 로딩이 안 뜹니다. 그래서 /explore를 서버 라우팅(새로고침)으로 만들어서 /home 캐시를 지우는 덥니다.

kraf님의 프로필 이미지
kraf
질문자

아 그래서 그랬던 거였군요!! 감사합니다ㅠ

그렇다면 혹시 말씀해주신 '/home 캐시를 지우는 겁니다.' 에서 캐시는 Next의 fetch메소드로 인한 캐시를 말씀하시는 건가요 아니면 리액트 쿼리의 prefetchInfiniteQuery 의 캐싱을 말씀하시는 건가요?

제 생각은, loading.tsx가 서버컴포넌트의 로딩이 되는 동안 적용되는 것인데,

  • /home 에 최초 접속하는 순간 page.tsx에서 사용되는 fetch메소드인 getPostRecommends 캐싱이 적용

  • 이를 queryFn으로 사용하는 prefetchInfiniteQuery 역시 캐싱이 되어서 결국은 둘 다 캐싱이 적용

     

 

그러므로 /home -> /explore -> /home 으로 이동하게 되면 /home의 데이터 fetch인 getPostRecommends 와 prefetchInfiniteQuery 둘 다 캐싱이 되어 있으므로 loading.tsx없이 바로 보여지는 것이라고 이해했는데 이게 맞을까요?

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

prefetchInfiniteQuery는 캐싱 기능이 없습니다. nextjs 서버사이드에서는 fetch가 캐싱이 되고, 클라이언트사이드에서는 layout과 page가 캐싱이 됩니다. 근데 getFollowingPosts는 제가 no-store를 걸어놔서 캐싱이 되지 않습니다.

kraf님의 프로필 이미지
kraf
질문자

안녕하세요 강사님. 계속 복습을 하던 도중에 확실히 짚고 넘어가고 싶은 부분이 생겨서 마지막 답글에 대해 이어서 질문드립니다.

" prefetchInfiniteQuery는 캐싱 기능이 없습니다. " 라고 말씀을 해 주셨는데,

(우선, prefetchInfiniteQuery와 prefetchQuery는 무한 스크롤의 차이를 제외하곤 캐싱 메커니즘이 동일하다고 알고 있으므로 prefetchQuery로 말하겠습니다 )

일반 클라이언트 컴포넌트에서 prefetchQuery는 캐싱기능이 존재하지만, Next의 서버컴포넌트에서 prefetchQuery를 진행할때는 (staleTime을 부여해도 )캐싱 기능이 존재하지 않는다는 말씀이신가요?

 

 

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

서버에서 prefetch한 데이터는 클라이언트에서 hydrate 받을 때 데이터만 이어지지 캐시 설정이 이어지진 않습니다. 캐시 설정은 useQuery에 따르는 거고요.

kraf님의 프로필 이미지
kraf
질문자

아 그렇군요 감사합니다!!

0

안녕하세요, 인프런 AI 인턴입니다.

Next.js의 로딩 메커니즘 및 리액트 쿼리의 isPending과 관련된 개념에 대해 궁금해 하시는군요. 관련하여 다음 질문에서 비슷한 내용의 답변이 이루어졌습니다.
질문자님께서 언급하신 “첫 페이지”의 개념에 대해 설명드리자면, 일반적으로 첫 페이지는 사용자가 사이트에 접속했을 때 처음으로 로딩되는 페이지를 말합니다. 최초 렌더링된 페이지가 해당되며, 이후 다른 페이지로 이동하고 새로고침을 통해 접근하는 페이지는 첫 페이지가 아닙니다.

또한, prefetchInfiniteQuery를 통한 데이터 fetching과 관련하여 서버 측에서 미리 데이터를 가져오는 경우와, 그로 인한 로딩 시간에 대해서도 질문해주셨는데, 이에 대한 답변 역시 아래 링크에서 확인하실 수 있습니다. 리액트 쿼리의 prefetch 기능은 컴포넌트가 마운트되기 전에 데이터를 미리 가져오는 것이 맞습니다. 따라서 실제 사용자에게 체감되는 로딩 시간에 영향을 미치지 않을 수 있습니다.

더 자세한 설명을 원하시면 아래 링크를 참고해 주세요.

이 정보가 질문자님의 궁금증을 해결하는 데 도움이 되길 바랍니다.

kraf님의 프로필 이미지
kraf

작성한 질문수

질문하기