MPA (Multiple Page Application)
: 사용자가 페이지를 요청할 때마다, 웹 서버가 요청한 UI와 필요한 데이터를 HTML로 파싱해서 보여주는 방식의 웹 어플레이케이션이다. 사용자가 아주 사소한 요청을해도 매번 전체 페이지를 랜더링 해주어야 한다.
SPA (Single Page Application)
: 하나의 HTML 파일을 기반으로 자바스크립트를 이용해 동적으로 화면의 컨텐츠를 바꾸는 방식의 웹 어플리케이션이다. 처음에 한 번만 정적 리소스를 다운받고, 그 이후에는 새로운 요청이 들어왔을 대 필요한 데이터만 부분적으로 바꾸어준다.
간단하게 다시 정리하자면 MPA는 다수의 페이지로 구성되어 요청마다 정해진 페이지를 반환하는 반면, SPA는 단일 페이지로 구성되어 해당 페이지 자체에서 요청에 따라 화면을 재구성합니다.
CSR은 클라이언트에서 HTML문서 렌더링을 할 것이냐 SSR은 서버사이드에서 HTML 문서를 렌더링 할 것이냐로 구분할 수 있습니다.
앞서 살펴본 MPA와 SPA 개념을 보면 각각 어떤 방식으로 렌더링을 하고 있는지 알 수 있을텐데요.
MPA는 SSR방식으로, SPA는 CSR 방식으로 HTML 문서를 렌더링하고 있습니다.
MPA 형태에서는 이미 하드코딩된 정적페이지들을 개별적으로 서버가 가지고 있다가 요청때마다 서버는 해당 요청에 상응하는 정적페이지를 하나 찾아서 반환해주게 됩니다. 이는 결국 렌더링이 서버에서 완료되어 최종 문서를 반환하고 있는 형태입니다.
SPA형태는 최초 요청시에 서버로부터 HTML 문서를 전달 받습니다. 해당 문서는 빈 HTML 문서나 다름없습니다. 최초로 받아온 HTML 문서를 가지고 렌더링에 필요한 기타 다른 파일들 (JS등..)을 로드하며 클라이언트단에서 렌더링을 하여 화면을 구성하게 됩니다.
여담으로 MPA === SSR 또는 SPA === CSR 개념으로 인지하는 경우도 있는데, 틀린 개념입니다. MPA/ SPA는 웹 어플리케이션을 구성하는 형태를 말하는 것이고, SSR / CSR은 렌더링을 어떻게하는지에 대한 방식을 말하는 것입니다. 다만, MPA는 SSR 방식만, SPA는 CSR 방식을 추구합니다. (전통적으로 ! 현재는 다양한 방식들이 존재합니다.)
위의 사진은 SSR의 단계를 설명합니다.
- User가 Website에 요청을 보낸다.
- Server는 'Ready to Render'. 즉, 즉시 렌더링 가능한 html 파일을 만든다. (리소스 체크, 컴파일 후 완성된 HTML 컨텐츠로 만든다.)
- 클라이언트에 전달되는 순간, 이미 렌더링 준비가 되어있기 때문에 HTML은 즉시 렌더링 된다. 그러나 사이드 자체는 조작 불가능 (Javascript가 읽히기 전)
- 클라이언트가 Javascript를 다운 받는다.
- 다운 받아지고 있는 사이에 유저는 컨텐츠는 볼 수 있지만 사이트를 조작할 수 없다. 이때 사용자의 조작을 기억하고 있는다.
- 브라우저가 Javascript 프레임워크를 실행한다.
- JS까지 성공적으로 컴파일 되었기 때문에 기억하고 있던 사용자 조작이 실행되고 이제 웹 페이지는 상호작용 가능해진다.
조금 더 간단한 SSR 단계 사진입니다.
즉, 서버에서 이미 '렌더 가능한' 상태로 클라이언트에 전달되기 때문에, JS가 다운로드 되는 동안 사용자는 화면에 그려진 UI를 볼 수 있다.
따라서 SSR 방식의 장점은 다음과 같은 것이 있다.
- User가 Website에 요청을 보낸다.
- CDN이 HTML파일과 JS로 접근할 수 있는 링크를 클라이언트로 보낸다. (CDN : aws의 cloudflare를 생각하면 됨. 엔드 유저의 요청에 '물리적'으로 가까운 서버에서 요청에 응답하는 방식)
- 클라이언트는 HTML과 JS를 다운로드 받는다.
(이때 SSR과 달리 유저는 아무것도 볼 수 없다.)- 생략
- 다운로드 완료된 JS가 실행된다. 데이터를 위한 API가 호출된다.
- 서버가 API로부터의 요청에 응답한다.
- API로 부터 받아온 data들을 제자리에 넣어준다. 이제 페이지는 상호작용이 가능하다.
부가설명 : 하나의 페이지에서 여러 페이지를 보여준다는 것은 결국엔 자바스크립트를 이용해서 페이지의 일부분이나 전체를 갈아치우는 것으로 생각해볼 수 있다. 리액트 라이브러리를 이용해 링크 이동과 같은 기능을 내부적으로 구현 시 Router를 설치하여 사용하지만 결국 이러한 파일(jsx 및 js)들은 (CRA 환경 이라면) Webpack과 같은 번들링 도구를 거쳐 하나의 (또는 여러개의 chunk파일로) 거대한 js파일로 번들링되게 될 것이다. SPA에서는 이처럼 번들링 된 js를 전달받아 Single Page Application을 구축하게 되는 것이다.
즉, 서버에서 처리 없이 클라이언트로 보내주기 때문에 Javascript가 모두 다운로드 되고 실행이 끝나기 전까지 사용자는 볼 수 있는게 없다.
그럼에도 CSR 방식은 다음과 같은 장점이 있다.
SSR은 초기 로딩 속도가 빠르고 SEO에 유리하다. CSR은 초기 로딩후에 View를 서버에 요청하는 것이 아닌 클라이언트에 직접 렌더링하기 때문에 화면 전환 속도는 매우 빠르다.
이 두가지 랜더링 방법을 적절하게 사용하여 첫 번째 페이지 로딩에서는 SSR을 사용하고, 그 후에 모든 페이지 로드에는 CSR 렌더링 방식을 활용하는 방법을 사용하게 된다.
=> 이러한 생각에서 탄생한 여러 프레임워크들이 존재한다. Vue의 경우엔 Nuxt.js가 대표격인 것 같고, React의 경우엔 Next.js / Gatsby.js 등이 있다. 물론 프레임워크를 사용하지 않고 순수 React에서 여러 설정들을 건드려 SSR을 지원하도록 할 수도 있다고 한다.
이렇게 SPA 형태에 SSR을 지원하도록 설정한다면,
첫 페이지 로딩은 SSR 방식으로 기존 CSR 방식보다 빠르게 문서를 받아옴과 동시에 해당 문서는 서버측에서 렌더링이 완료되었으므로 SEO 적용 또한 가능하다. 그 이후에 렌더링 될 페이지는 그 사이 번들링 된 js 파일을 받아서 CSR 방식으로 수행한다면 두 가지 렌더링 방식들이 가지고 있던 장점들을 살릴 수 있다. 즉, SPA 형태에서 두 가지 렌더링 방식을 적절히 혼합해 사용함으로써 기존 방식들이 가지고 있던 단점을 극복하는 것이다.