Next.js는 React의 기존 렌더링 방식인 CSR(Client Side Rendering)의 단점을 해결하기 위해 등장한 프레임워크이다. 이 글에서는 Next.js의 사전 렌더링이 CSR의 단점을 어떻게 개선하는지 살펴보고자 한다.
CSR은 React의 기본 렌더링 방식으로, 클라이언트(브라우저)에서 직접 화면을 렌더링한다. 이 방식에서는 사용자가 웹 페이지에 접속할 때 다음과 같은 흐름으로 렌더링이 진행된다.
사용자가 웹 페이지에 접속하면, 브라우저를 통해서 초기 접속 요청을 서버에게 보냄.
서버는 빈 HTML 파일(ex: index.html)을 브라우저에 보냄.
브라우저는 이 HTML 파일을 렌더링하지만, 초기에는 빈 화면만 표시됨. (현재 브라우저가 서버로부터 받은 html파일은 빈 껍데기 역할을 하는 html파일이니까)
서버는 후속으로 모든 React 컴포넌트와 로직이 포함된 JS 번들 파일을 전송한다.
브라우저는 서버로부터 받은 번들링 된 JS파일(React앱)을 직접 실행함.
이 JS파일은 React앱이기 때문에 이 React앱을 브라우저가 실행하게 되면, 우리가 만든 React컴포넌트들이 이때가 되어서야 실제로 화면에 나타나게 됨.
이 방식의 가장 큰 장점은, 초기 접속 후 페이지 이동이 매우 빠르다는 것이다. 브라우저에게 전송되는 이 JS번들파일(React앱)에는 현재 초기접속 요청이 들어온 페이지에 필요한 컴포넌트들 뿐만 아니라, 이 사이트 내부에서 접근할 수 있는 모든 페이지에 필요한 컴포넌트들이 다 들어있음. (웹 사이트에 필요한 전체 코드)모든 페이지의 컴포넌트가 이미 클라이언트에 로드되기 때문에, 추가적인 서버 요청 없이 브라우저 내에서 페이지가 전환된다.
그렇기 때문에 초기접속 요청 이후에 사용자가 웹 페이지의 링크나 버튼을 클릭해서 페이지를 이동하게 되더라도 서버에게 새로운 페이지를 요청할 필요가 없음. 이미 브라우저는 React앱을 가지고 있기 때문 (모든 페이지에 필요한 컴포넌트가 다 있음)
그래서 브라우저가 자체적으로 서버로부터 받은 React앱을 실행해서 현재 이동해야 하는 페이지에 맞도록 적절히 컴포넌트를 갈아끼우면 돼서 굉장히 빠른 속도로 쾌적하게 페이지 이동이 가능하게 됨.
초기접속 속도가 느려짐.
초기접속 요청이 발생한 시점부터 실제로 화면이 렌더링 되기 까지 꽤 오랜 시간이 소요가 됨.
브라우저가 화면에 컨텐츠를 렌더링하기까지html파일, JS번들(React앱) 파일도 받아와야 하고 최종적으로 이 React앱을 실행까지 마쳐야 하기 때문에 브라우저가 할 일이 많아서 FCP(First Contentful Paint), 즉 사용자가 실제 콘텐츠를 볼 수 있게 되는 시점까지 걸리는 시간이 길어진다. 이로 인해 사용자는 빈 화면을 보게 되고, 특히 FCP가 3초 이상 지연되면 이탈률이 크게 증가할 수 있다.
"요청 시작"시점으로부터 컨텐츠가 화면에 처음 나타나는데 걸리는 시간
웹페이지의 성능을 대표할 정도로 굉장히 중요한 지표임.
3s 이상: 이탈률 32%증가.
5s 이상: 이탈률 90% 증가.
6s 이상: 이탈률 106% 증가.
10s 이상: 이탈률 123% 증가.
Next.js는 이러한 CSR의 단점을 해결하기 위해 사전 렌더링(Pre-rendering)이라는 새로운 렌더링 방식을 도입했다. 사전 렌더링은 서버 측에서 모든 React 컴포넌트를 미리 HTML로 변환한 후 브라우저에 전달하는 방식으로 그 과정은 다음과 같다:
유저가 브라우저를 통해서 초기접속 요청을 보냄.
서버가 서버측에서 JS로 작성된 React 컴포넌트들을 직접 실행시켜서 모든 React컴포넌트들을 HTML로 변환. (사전에 렌더링을 수행)
변환된 HTML 파일을 브라우저에 응답으로 보냄. 서버측에서 이미 사전에 렌더링이 완료된 HTML 파일을 보냈기 때문에 사용자는 접속하자마자 완성된 콘텐츠를 볼 수 있게 된다. 즉, FCP 시간을 크게 단축할 수 있다.
Next서버가 곧바로 후속으로 React 앱 전체를 번들링한 JS 파일을 브라우저로 전송.
브라우저는 서버로부터 받은 JS파일(React앱)을 직접 실행해서 현재 화면에 렌더링 되어있는 HTML요소들과 연결을 시켜줌. (수화(Hydration) 작업을 진행)
Next.js는 초기 접속 요청에 대해 사전 렌더링을 사용해 빠르게 콘텐츠를 표시하고, 이후 페이지 이동은 CSR 방식으로 처리한다. 이는 사용자가 초기 페이지를 빠르게 접속할 수 있도록 하면서도, 이후 페이지 이동 시 React의 SPA(Single Page Application) 장점을 그대로 유지할 수 있게 해준다.
브라우저가 서버에게 별도의 페이지를 요청하지 않고, 그냥 직접 브라우저 측에서 JS코드를 실행해서 (React앱) 컴포넌트를 교체하는 방식으로 페이지 이동이 효율적으로 진행됨.
이렇게 진행되는 이유는, 앞선 초기접속 요청 과정에서 서버가 브라우저에게 hydration을 위해서 JS번들파일(React앱)을 전달해줬기 때문.
JS번들 파일은 사실상 React컴포넌트들이 들어있는 React앱이다. 그래서 페이지 이동이 발생했을 때 원래 React앱이 그랬던대로 브라우저가 직접 JS코드를 실행해서 컴포넌트만 교체하는 식으로 빠르게 페이지 이동이 가능함.
Next.js의 사전 렌더링은 CSR 방식의 느린 초기 접속 문제를 해결하여 기존 React단점이었던 FCP를 빠르게 개선할 수 있으면서도, 페이지 이동은 기존의 CSR방식으로 그대로 처리하여, 빠른 페이지 전환이라는 장점을 유지할 수 있게 해준다.
따라서 SEO를 고려한 웹사이트나, 초기 로딩 성능이 중요한 프로젝트에서 Next.js는 React의 한계를 극복한 효율적인 선택이 될 수 있다.