Next.js 페이지 렌더링 이해하기

곽태욱·2021년 1월 24일
10

React 이해하기

목록 보기
4/4

기존에 웹 사이트 렌더링이 어떻게 이뤄졌는지 알아보면 Next.js의 페이지 렌더링 방식을 이해하는데 도움이 됩니다.

Static Site Generation

정적 페이지 생성 방식은 1990년대 웹에서 많이 쓰였고, 지금은 거의 변경되지 않는 웹 페이지(이용 약관 페이지 등) 최적화에 쓰입니다.

처음에 웹 개발자는 코드를 빌드해서 HTML과 CSS 파일 묶음을 생성합니다. (옛날에는 js 파일을 거의 제공하지 않았지만 요즘은 제공하기도 한다.) 그리고 서버의 80번 포트에 HTTP 요청을 처리하는 프로세스(웹 서버)를 생성하고 거기에 이 파일 묶음을 업로드합니다.

그리고 클라이언트(브라우저)에서 80번 포트로 HTTP GET 요청을 보내면 웹 서버는 내부 스토리지로부터 필요한 HTML과 CSS, 이미지 파일 등을 불러와서 응답해줍니다. 이때 서버에서 따로 HTML을 생성하는 것이 아니라 일반적으로 빌드 시점에 생성된 HTML 파일을 그대로 보내줍니다. 그래서 모든 사용자에게 항상 동일한 파일이 반환됩니다.

서버로부터 HTML(+CSS,이미지) 파일을 받은 클라이언트는 이 파일을 가지고 클라이언트 브라우저 내에서 DOM, CSSOM, 렌더 트리 등을 생성해 브라우저 화면을 그립니다.

장점

80번 포트로 들어오는 HTTP 요청만 처리하면 되기 때문에 웹 서버가 가볍습니다.

단점

만약 HTML에 변경 사항이 있으면 다시 빌드해서 웹 서버에 업로드해야 합니다.

마이페이지와 같이 사용자 요청에 따라 다른 HTML을 반환해야 하면, 빌드 시 모든 경우의 HTML을 미리 만들어야 합니다.

Next.js

Next에선 getStaticProps 함수를 통해 HTML 파일에 들어갈 데이터를 빌드 시점에 넣어줄 수 있습니다. 옛날에는 HTML 파일을 직접 생성하고 데이터를 넣어줘야 했던 것과 다르게, React 코드로 HTML 파일을 자동으로 생성할 수 있어 편리합니다.

Server-Side Rendering

정적 페이지 생성의 단점을 개선하기 위해 웹 서버가 하는 일을 확장한 동적 페이지 생성 방식이 등장했습니다. 이 방식에서 서버는 80번 포트로 들어오는 클라이언트의 HTTP 요청을 처리할 뿐만 아니라 클라이언트의 요청 내용에 따라 HTML 파일을 동적으로 생성해서 응답해주기도 합니다.

클라이언트가 서버의 특정 URL로 HTTP GET 요청을 보내면, 서버의 해당 URL과 연결되어 있는 HTML 파일 생성 로직을 실행한 후 서버에서 갓 생성된 HTML(+CSS,JS) 파일을 클라이언트로 반환합니다. 일반적으로 요청에 명시되어 있는 URL에 따라 서버에서 다른 HTML 생성 로직이 실행됩니다. 이후 클라이언트는 응답 받은 HTML 파일을 토대로 브라우저 화면을 그립니다.

우리가 페이지를 전환하기 위해 브라우저에 있는 <a> 태그를 클릭하면 브라우저는 그 태그의 href에 적힌 URL로 GET 요청을 보냅니다. 그래서 클라이언트에서 페이지를 전환할 때마다 서버로 해당 HTML을 요청하기 때문에 매 페이지 전환 시 네트워크 지연이 발생할 수 있습니다.

동일한 요청 내용에 대해선 기존에 생성된 HTML을 반환하는 캐싱 기법도 존재합니다.

장점

사용자의 요청에 따라 변하는 HTML 파일을 미리 일일이 만들어 놓지 않아도 됩니다.

단점

정적 페이지 생성 방식보다 하는 일이 많아서 서버가 무거워집니다.

Next.js

Next에선 getServerSideProps 함수를 통해 HTML 파일을 클라이언트 요청에 따라 다르게 생성할 수 있습니다. 이 함수는 클라이언트가 해당 HTML을 요청했을 때 서버에서만 실행됩니다.

Client-Side Rendering

React 이후 웹 구조

Single Page Application (SPA)

Single Page = HTML 1개

React는 기본적으로 1개의 HTML 파일을 가지고 화면을 렌더링하는 Single Page Application으로서 HTML DOM 노드를 생성-수정-삭제하거나 페이지 라우팅을 처리하는 과정은 모두 클라이언트 측(브라우저)에서 발생합니다. 반면 이와 반대 개념인 Multi Page Application은 여러 HTML 파일을 이용해서 페이지 생성 및 라우팅을 처리하는 방식의 앱입니다.

장점

서버로 HTML 파일을 요청하지 않기 때문에 페이지 전환 시 네트워크 지연이 발생하지 않아 빠릅니다.

단점

서버에서 실행되던 HTML 렌더링 로직이 포함된 React.js 라이브러리 번들을 브라우저에 다운로드 받아야 하기 때문에, 브라우저 데이터 삭제 후 첫 React 사이트에 접속할 때는 응답 속도가 느립니다.

일반적인 SPA에서 라우팅을 포함한 대부분의 애플리케이션 로직은 클라이언트로 전송되는 번들 JavaScript 파일에 캡슐화됩니다. 이러면 너무 많은 요청을 처리 할 필요가 없기 때문에 웹 서버의 부담을 덜어줄 수 있지만, 전체 애플리케이션 로직을 클라이언트로 보내야하기 때문에 클라이언트의 초기 로드가 느려집니다.

Universal Rendering

위 3가지 방식을 장점 위주로 섞어 놓은 형태

웹사이트를 보여주기 위해 필수적인 HTML, CSS 파일은 웹 서버에서 처리하고, 사용자 상호작용을 처리하기 위한 JS 파일은 Content Delivery Network(CDN)에 배포하는 방식입니다. 이렇게 HTML, CSS만 먼저 보내 First Contentful Paint(FCP) 시간을 단축시키고, 나중에 다운받은 JS 파일을 통해 사용자 상호작용을 활성화하는 방식을 수화(Hydration)라고 합니다.

다른 용어로 Isomorphic Rendering 이라고도 합니다.

장점

웹 서버에서 브라우저로 바로 애플리케이션의 중요한 부분인 HTML과 CSS 파일을 주기 때문에 초기 페이지 렌더링 속도(FCP)가 빠릅니다. 반면에 CSR은 페이지 렌더링에 필요한 모든 외부 데이터(예: React.js 번들)를 가져올 때까지 화면을 렌더링할 수 없습니다.

단점

React.js 라이브러리만으론 구현하기 어려웠지만, 최근 Next.js 프레임워크가 등장해서 Universal Rendering을 구현하기 수월해졌습니다.

profile
이유와 방법을 알려주는 메모장 겸 블로그. 블로그 내용에 대한 토의나 질문은 언제나 환영합니다.

0개의 댓글