Next.js에서 제공하는 dynamic 옵션을 활용해 초기 로딩 속도를 개선한 경험을 정리해보겠다.
Next.js 공식 문서에 따르면 dynamic은 lazy와 Suspense를 합성한 것이다.
즉, lazy의 코드 스플리팅과 loading 옵션을 이용한 Suspense의 Fallback 기능을 동시에 사용할 수 있다.
따라서 무거운 컴포넌트의 초기 로딩 비용을 줄이고, 필요한 순간에만 불러오는 방식으로 사용자 경험을 개선할 수 있다.
네트워크 환경을 Slow 4G로 설정해 진행한 환경임을 미리 알립니다.
우선 개선 전 영상을 보겠다.

“개발 로드맵”을 클릭했지만, 다음 화면이 나타나기까지 시간이 오래 걸린다.

Performance 탭에서 녹화해 확인해보니 RSC Payload를 모두 받은 뒤에야 페이지 전환이 일어났고, 페이지 전환까지 약 7초가 걸렸다.
이는 필요한 모든 청크를 받아오지 못하면 클라이언트가 화면을 렌더링하지 않기 때문이다.
그 결과, 사용자 입장에서는 마치 페이지가 멈춘 것처럼 보이게 된다.
ReactFlow 라이브러리를 사용하는 컴포넌트쪽이 무겁다고 판단됐고, 해당 컴포넌트와 다른 몇 개의 컴포넌트에도 dynamic을 적용해 보았다.
const ReactFlowCanvas = dynamic(
() => import("@/components/(with-side-bar)/topic/react-flow-canvas"),
{
ssr: false,
loading: () => (
<div className="flex h-full w-full items-center justify-center">
<Spinner className="text-muted-foreground size-16" />
</div>
),
}
);
이후 결과는 다음과 같았다.


Performance 탭에서 다시 확인해보니 화면 전환까지 걸린 시간이 약 2초로 줄어들었다.
개선 전 약 7초 → 개선 후 약 2초로, 3배 이상의 성능 개선을 확인할 수 있었다.
특히 네트워크가 느린 환경에서도 사용자 경험이 크게 개선된 것을 확인할 수 있었다.
처음에는 dynamic과 lazy의 차이를 명확히 알지 못했다. 하지만 실제 프로젝트에 적용해보면서 dynamic은 lazy + Suspense가 결합된 형태이며, 이를 적절하게 사용하면 초기 로딩 속도, 화면 전환 성능 개선에 크게 기여할 수 있다는 점을 알게 되었다.