오랜만입니다!
오늘은 웹페이지가 만들어지는 방법들과 그 장단점을 알아보겠습니다.
이번 포스트에서 소개할 방법은 크게 네가지가 있는데요,
- Client Side Rendering (CSR)
- Server Side Rendering (SSR)
- Static Site Generation (SSG)
- Incremental Static Regeneration (ISR)
정도가 있겠습니다.
지금까지의 리액트에서는 CSR이라고 부르는 방법으로 페이지를 랜더링 해 왔습니다. 후에 설명하겠지만, 기존에 사용하던 SSR이라는 전통적인 방식은 너무 느리고 페이지를 Interactive하게 만들기 어려웠습니다. 그리하여 리액트는 새로운 방식의 CSR을 채용했고, 클라이언트에 기본이 될 html 뼈대와, 살을 붙힐 js파일을 보내서 클라이언트쪽에서 페이지를 랜더링 하게끔 만들었습니다. 다만, 필요한 정보는 페이지 랜더링이 끝난 후에 추가적인 통신을 통해서 가져와 다시 랜더링을 하게끔 했습니다.
당연히 초기에는 CSR이 SSR보다 빨랐다고 합니다. 인터랙션도 클라이언트 레벨에서 다루기 때문에 빨랐구요. 또한 lazy loading을 지원해 랜더링이 오래걸리는 사진이나 동영상을 필요한 때에 랜더링을 하여 속도를 높혔습니다. 하지만, 점차 높은 레벨의 페이지가 등장하면서, js 코드는 많아지고, 또 그만큼 초기 구동이 늦어지면서, SSR보다 오히려 느려지는 상황이 발생하기 시작합니다. 부수적으로, 초기 페이지에는 html 뼈대만 날라오기때문에, 구글 검색엔진에 노출이 되지 않는 SEO(Search Engine Optimization)문제도 발생합니다.
아직 Node.js가 보편화되기 전까지는, 주로 서버가 자바 기반의 JSP/Servlet 형태로 개발되었다고 합니다. SSR은 이당시 주로 사용되던 방법으로, html문서를 완성시켜서 클라이언트에게 주는 전통적인 방식입니다. 위에서 얘기했듯이, SSR은 초기 랜더링이 CSR보다는 느리지만, 서버에서 html을 완성시켜 오는 형태이기때문에, 로딩시간이 상대적으로 짧습니다. 또한 SEO 문제도 해결하고, CSR보다 세션관리가 용이해집니다.
물론 엄밀하게 말하면, SSR가 페이지를 먼저 띄울수는 있어도, js파일이 오기 전까지는 인터랙션이 불가능합니다.
위의 두 다이어그램이 랜더링 프로세스를 간략하게 보여주고 있는데요, SSR은 보시다시피 페이지를 볼 수 있는 시점과, 인터랙션이 가능한 시점이 다릅니다. 반면, CSR은 그 시점이 같습니다. 이외에 단점으로는, SSR은 서버에서 하는 일들이 굉장히 많아집니다. 서버를 수준있게 짜야함은 물론이고, 리소스까지 많이 차지하는 방식입니다.
위의 두가지 방식이 적절히 섞이면 최대의 효율이 나지 않을까라는 생각 해보셨나요? 그래서 탄생하게 된 프레임워크가 Next.js 입니다. 첫 랜더링은 서버에서 진행해 SEO를 해결하고, 인터랙션은 CSR 방식을 채택해 서버에 스트레스가 가지 않게끔 하는것이 이 프레임워크의 목표입니다. 리액트 자체에서도 이런 아키텍쳐를 구현하게끔 여러 메서드를 넣어 놨지만, Next.js가 좀 더 범용적이고, 다른 기능도 많이 때문에, 많이 사용되고 있습니다. 조금더 자세히 말하면, Next.js는 모든 페이지를 기본적을 빌드타임에 프리랜더링을 해놓습니다. 즉, 필요한 데이터를 다 들고, 클라이언트에 쏠 준비를 마친상태로 빌드가 된다는 것이죠. 이러한 방식을 SSG라고 하며, 발전형인 ISR도 Next.js에서 지원하고 있습니다.
많은 개발자들이 SEO를 해결하려 CSR에서 SSR로 회귀 하기도 했습니다만, 다른 개발자들은 SSG을 통해 해결하려고도 했습니다. 기존 방식인 SSR은 서버 런타임동안 페이지를 생성, 송신을 하느라 시간이 오래 걸렸다라면, SSG를 통해 빌드타임때 미리 생성된 페이지를 보내주기만 함으로서 시간을 단축시키려는 목적이었습니다. 하지만, 이 방식은 기본적이고도, 치명적인 단점이 있는데, 업데이트된 데이터를 담지 못한다는 겁니다. 이미 구성된 html을 건드리지 못하는 셈이죠. 그래서 등장한것이 ISR이 되겠습니다.
간단히 얘기해서 정해진 시간마다 데이터를 fetch해와서 CSR방식으로 페이지를 재구성 하는겁니다. 그러면 데이터의 변화가 있어도, 일정 시간안에는 최신의 데이터를 반영할 수 있게 됩니다. Next.js에서는 SSG와 ISR 방식으로 페이지 랜더링을 진행하게 됩니다. 하지만, 그 주기가 클래식한 SSR보다는 떨어질 수 있어서, 최신 데이터를 빠르게 소비해야 하는 웹페이지에서는 ISR보다 SSR을 더 많이 사용하게 됩니다.
지금까지 4개의 페이지 랜더링 방식을 알아보았습니다. 뭔가 순서를 너 나은 식으로 한거 같은데, 꼭 그렇지만은 않습니다. SCR은 오히려 SEO를 피하고 싶을때 유용하게 쓸 수 있고, 지속적인 데이터의 변화가 없는 Landing page 이라면 SSG가 최고의 성능을 낼 수 있습니다. 따라서 4개의 방법의 장단점을 잘 파악하고 있는게 중요할 것 같습니다!
https://tsh.io/blog/ssr-vs-ssg-in-nextjs/
https://prismic.io/blog/how-to-improve-core-web-vitals
https://medium.com/walmartglobaltech/the-benefits-of-server-side-rendering-over-client-side-rendering-5d07ff2cefe8
https://d2.naver.com/helloworld/7804182
https://theodorusclarence.com/blog/nextjs-fetch-method#conclusion
https://www.sarah-note.com/%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9/posting2/