📍동시에 여러개의 fetching?
🧐 의문점
보통 웹사이트를 제작하다보면 한 페이지에 여러개의 api를 호출해야 하는 경우가 자주 생긴다.
기존에 nextjs를 사용할 때에는 useQuery, useSWR을 사용해서 키값을 이용해서 페이지에 접근하자마자 동시에 api를 호출했다. 하지만 새로나온 nextjs14의 기능을 이용하려면 함수를 통해 api를 호출한다.
여기서 문제가 발생한다.
우선 내가 a, b 이 두곳의 api를 호출한다 가정해보자.
const aData = await getAData(); // time : 10s const bData = await getBdata(); // time : 1s
코드를 보면 a정보를 fetch한 뒤 b정보를 fetch한다. 즉 동시에 api를 호출하는 것이 아니라 순차적으로 호출을 하게 된다. 이렇게 되면 이 페이지가 로딩되는데 까지 11s나 걸리게 된다.
- 그렇다면 동시에 api호출을 해서 10s로 로딩시간을 줄일 수는 없을까?
- 먼저 끝나는 정보는 다른 정보를 받아오기 전에 미리 사용자가 볼 수 있게 뿌려줄 수 없을까? => 둘 다 가능하다.
1. 동시에 api호출
export default async function MovieDetail({ params: { id }, }: { params: { id: string }; }) { console.log("==========="); console.log("start fetching"); const [movie, videos] = await Promise.all([getMovie(id), getVideos(id)]); console.log("end fetching"); return <h1>{movie.title}</h1>; }
실행결과 =========== start fetching Fetching movies: 1708851811564 Fetching videos: 1708851811564 end fetching
순차적으로 호출하지 않고 동시에 호출해서 각각의 데이터들을 배열안에 담아주었다.
이렇게 되면 다른하나가 끝날때까지 기다리지 않아도 된다.
2. 동시에 api호출 + 먼저 끝나는 정보는 먼저 보여주기
더 최적화를 해보자.
먼저 끝나는 정보는 먼저 보여주면 UX측면에서 훨씬 이득일 것이다.
우선 getMovie, getVideos라는 함수와 함께 그 함수를 통해 받은 정보를 이용하는 코드들을 컴포넌트화 한다.
async function getMovie(id: string) { const response = await fetch(`${API_URL}/${id}`); return response.json(); } export default async function MovieInfo({ id }: { id: string }) { const movie = await getMovie(id); return <h6>{JSON.stringify(movie)}</h6>; }
위 코드처럼 2개를 분리시킨다.
export default async function MovieDetail({ params: { id }, }: { params: { id: string }; }) { return ( <div> <h3>Movie detail page</h3> <Suspense fallback={<h1>Loading movie info</h1>}> <MovieInfo id={id} /> </Suspense> <Suspense fallback={<h1>Loading movie videos</h1>}> <MovieVideos id={id} /> </Suspense> </div> ); }
그 후 Suspense라는 컴포넌트로 감싸준다.
참고 : (Suspense = 미결) 즉 아직 fetch가 완료되지 않아서 잠시 기다려달라는 뜻. React기능임,,,
=> 그 동안 fallback이랑 놀고있어~ 나중에 내 자식컴포넌트 데리고 올게.
이렇게 되면 각각 동시에 따로 fetch과정이 실행되는데 만약 fetch가 오래걸리면 Suspense컴포넌트에 fallback함수가 실행되어 loading state를 만든다. 그 후 fetch가 완료되면 fallback을 종료하고 자식컴포넌트를 실행시킨다.
결국 각각 fetch가 빨리끝나는대로 바로 화면에 데이터값들을 뿌려줄 수 있게 된다.