Next.js을 사용하면서 다른 페이지로 이동을 할 때 가만히 멈춰있는 화면을 본 적이 있을 것입니다.
특히 처음으로 페이지로 이동할 때 많이 보입니다.
Next.js는 SSR
(서버 사이드 렌더링)이다. 페이지로 전환 해보면 getServerSideProps
가 호출 되는걸 알 수 있습니다.
이동을 할 떼 next/link
또는 next/router
를 이용하는데 페이지를 전환하면 SSR
이 적용된 페이지는 서버에서 getServerSideProps
를 호출하고 데이터를 JSON
으로 반환합니다.
getServerSideProps
는 브라우저가 아닌 서버에서 호출하기 때문에 응답이 올 때까지 페이지가 멈춰 있는듯한 느낌을 받게 됩니다.
이런 경우에는 dynamic
으로 CSR
로 변경을 해주면 됩니다.
만약 해줘도 속도가 별 차이가 안 날 경우 로딩 처리를 해줘도 괜찮다고 생각해서 나는 로딩 처리를 해줬다. (속도가 그렇게 느리지는 않았다.)
라우팅에 이벤트를 적용시켜줘서 로딩을 처리하는 방법입니다.
_app.tsx
에 적용 시켜준다.
const [loading, setLoading] = useState(false);
useEffect(() => {
let timer: NodeJS.Timeout | undefined;
const start = () => {
setLoading(true);
};
const end = () => {
setLoading(false);
};
Router.events.on('routeChangeStart', start);
Router.events.on('routeChangeComplete', end);
Router.events.on('routeChangeError', end);
return () => {
Router.events.off('routeChangeStart', start);
Router.events.off('routeChangeComplete', end);
Router.events.off('routeChangeError', end);
clearTimeout(timer);
};
}, []);
routeChangeStart(url, { shallow })
: 라우트가 변경되기 시작할때 트리거됩니다.
routeChangeComplete(url, { shallow })
: 라우트가 완전히 변경되었을 때 트리거됩니다.
routeChangeError(err, url, { shallow })
: 라우트 변경 중에 에러가 발생했거나, 취소되었을 때 트리거됩니다.
적용을 시켜주는 것은 다른 로딩을 처리하는 것 과 같습니다.
return (
{loading ? (
<Loading />
) : (
<Component {...pageProps} />
)}
)
저 같은 경우는 로딩 컴포넌트를 따로 만들어서 적용 시켜줬습니다.
이제 이동할 경우에는 로딩 페이지를 확인할 수 있을 것이다.
로딩을 추가시켜 주는 것까지 좋았습니다. 하지만 페이지를 이동할 때마다 로딩 페이지가 적용됐습니다.
첫 페이지 속도만 느리고 다음에는 빠른 속도로 이동해버려도 로딩 페이지가 적용됐습니다. 이럴 경우 오히려 독이 됐습니다.
이럴 때를 대비해서 시간을 추가했습니다.
let timer: NodeJS.Timeout | undefined;
const start = () => {
// 시작 시 타이머 설정
timer = setTimeout(() => {
setLoading(true);
}, 500); // 0.5초 후에 로딩 상태를 설정
};
const end = () => {
// 끝나면 타이머 클리어
clearTimeout(timer);
setLoading(false);
};
시작할 경우 timer
를 추가시켜서 0.5초가 초과할 경우 로딩 상태를 설정해주게 했습니다.
끝나면 타이머도 같이 끝내줬습니다.
이럴게 해주면 빠른 속도로 페이지를 해버리면 로딩을 생략하게 됩니다.
코드 분할을 해도 속도 차이가 안나지만 첫 페이지 이동에서 느린 속도를 가진다면 위의 방법을 적용해줘도 나쁘지 않을 것 같습니다.