라이브러리와 프레임워크는 모두 개발자가 반복적인 작업을 줄이고, 효율적으로 코딩을 할 수 있도록 도와주는 도구이다. 하지만 라이브러리는 주도권(Control)을 개발자가 가지고 프레임워크는 주도권(Control)을 프레임워크가 가진다는 차이점이 있다. 라이브러리는 개발자가 필요할 때 함수나 기능을 호출해서 사용하는 반면에, 프레임워크는 개발자가 정해진 프레임워크의 틀에 맞춰 코드를 작성해야한다. 프레임워크와 같은 경우를 제어의 역전(Inversion of Control)라고 한다.
웹페이지의 모든 렌더링 작업이 클라이언트(브라우저)에서 일어나는 방식이다.
사용자가 브라우저를 이용해 초기 접속을 서버에게 요청하면 웹서버는 빈 껍대기 index.html을 브라우저에게 보내주고 브라우저는 빈 화면을 렌더링 해준다. 이후 서버는 자바스크립트로 작성된 모든 React코드를 하나의 자바스크립트로 묶어서(JS Bundle) 브라우저에게 보내준다. 그러면 브라우저는 번들링된 자바스크립트 파일(리액트 앱)을 직접 실행하고, 컴포넌트들을 화면에 렌더링 시켜준다.
CSR은 페이지 이동이 매우 빠르고 쾌적하다는 장점이 있지만 초기 속도가 느리거나 화면이 비어있을 수 있고 SEO에 불리하다.
요청 시작으로부터 컨텐츠가 화면에 처음 나타나는데 걸리는 시간인 FCP(First contentful Paint)는 매우 중요하다. FCP가 3초 이상이면 이탈률 32%증가, 5초 이상이면 90% 증가일정도이다.
사전 렌더링 때문이다.
사용자가 브라우저를 통해 초기 접속 요청을 보내면, 웹 서버에서는 자바스크립트 코드인 모든 리액트 컴포넌트를 실행해서 HTML 페이지로 미리 렌더링(JS 실행 렌더링. 화면 렌더링과 동음이의) 해놓는다. 이후 렌더링이 이미 완료된 HTML 파일을 브라우저에게 응답해 준다. 브라우저는 이 HTML 파일을 화면에 렌더링해준다. 그러면 FCP(First Contentful Paint)가 CSR(Client Side Rendering)에 비해 줄어드는 성능 최적화가 된다.
이 화면에 그려진 컨텐츠들은 HTML 파일이기 때문에 사용자와 상호작용(인터랙션)은 불가능하다. 상호작용은 JavaScript가 처리하는 영역이기 때문이다. 웹페이지의 상호작용을 동작하게 하기 위해 Next.js 서버는 브라우저에게 후속으로 모든 자바스크립트 코드(리액트 앱)를 번들링(JS Bundle)해서 브라우저에 보내준다. 브라우저는 그 코드를 직접 실행해서 현재 화면에 렌더링되어 있는 HTML 요소들과 연결하여 상호작용이 가능하게 해준다.
이렇게 HTML 코드로만 된 웹페이지에 자바스크립트 코드가 연결되어서 생기 있는 페이지가 되는 과정을 Hydration(수화)이라고 한다. 메마른 HTML에 자바스크립트라는 비가 내리는 것이다! 상호작용까지 가능하게 된 시점을 TTI(Time To Interactive)라고 한다.
Hydration이 완료된 이후에 발생하는 페이지 이동은 CSR(Client Side Rendering)과 똑같은 방식으로 처리된다.
이처럼 Next.js는 CSR(Client Side Rendering)의 단점(느린 로딩, SEO 문제)을 SSR(Server Side Rendering)과 SSG(Static Site Generation)의 방식을 통해 해결하는 프레임워크이기 때문에 사용한다.