CodeLyst

[React Rendering Pattern] Server Side Rendering

#React@kkiyya
thumb nail

Server-Side Rendering (SSR)

서버에서 완전한 페이지를 그린 HTML을 만들어 응답값으로 브라우저로 보낸 후 화면에 표시하는 기법입니다.

따라서, 클라이언트 측에서 렌더링하는 코드가 필요하지 않습니다.

웹을 그리는 방식 중에서 가장 오래된 방식이라고 합니다.

image

SSR은 서버에서 모든 HTML을 만들고 난 후에 클라이언트로 보내지기 때문에, 트래픽이 많아지면 서버의 부하가 생길 수 있습니다.

이런 서버의 과부하를 덜하기 위해 SSG라는 것도 있는데, 이건 다른 게시물로 소개드리겠습니다.


장점


FCP와 TTI의 감소

먼저, FCP와 TTI는 웹 사이트 성능 메트릭으로 이 것이 무엇인지에 대해서는 아래 글에서 따로 정리해두었습니다. 참고 후 봐주시면 좋을 것 같습니다.

CSR를 HTML를 받고 링크된 JS를 서버로 요청하고 응답 받고 또 실행까지 해야되는 경우가 있어 서버와 요청 왕복이 발생합니다. 하지만 SSR은 랜더링을 위한 잘 만들어진 HTML를 받고 바로 랜더링하기 때문입니다.

CSR

  • CSR은 HTML을 받고, HTML에 링크된 JS를 다운받고 실행하여 보여주는 과정이있어서 FCP와 TTI가 될때까지 시간이 많이 걸렸습니다.

SSR

  • SSR은 렌더링을 위해 완전한 HTML을 받고 렌더링하기 때문에, FCP 시간이 비교적 적습니다.
  • 서버에서 페이지 로직 및 렌더링을 실행하면 많은 자바스크립트를 클라이언트에 보내지 않아도 되므로 TTI가 빠르게 처리될 수 있습니다.

image

출처 :https://developers.google.com/web/updates/2019/02/rendering-on-the-web


SEO 가능

Search engine crawler가 요청에 대한 응답으로 완전한 HTML을 받기 때문에, 크롤링하기에 좋습니다.

예시로, Next.js로 웹 페이지를 만들면 OpenGraph라고 해서, 웹사이트 정보를 미리 보여주는 기능을 사용해 볼 수 있습니다.


단점


깜빡거림

웹 페이지를 그대로 받기 때문에 웹 페이지를 이동 할 때마다 깜빡이는 현상이 있을 수 있습니다.


느린 TTFB

TTFB란 (Time To First Byte), HTTP 요청을 했을때 처음 byte (정보) 가 브라우저에 도달하는 시간을 의미합니다.

  • 여러명의 동시 사용자가 발생하면, 서버에 부하가 걸릴 수 있습니다.

Full-page reloads

유저의 요청에 의해서 (유저의 행동에 의해서) 페이지가 렌더링 될때마다 서버에서 full HTML을 다시 생성하여 응답값을 보내주는 방식입니다. 따라서, 유저가 한 행동에 비해 굉장히 오랜 시간을 reload하는데 걸리는 단점이 있을 수 있습니다.

이런 것을 막기 위해서 server에서 렌더링을 할 수도 있고, client측에서 렌더링을 할 수 있도록 제공하는 라이브러리와 프레임워크를 제공합니다.


Server Rendering with NEXT.js

getServerSideProps return props 값에 따라서 각각의 요청에 대한 페이지를 pre-rendering합니다.

해당 기능은 브라우저에서 실행되지 않고, 오직 server에서만 동작합니다.

  • pre-rendering을 할 때 필요한 데이터를 포함 시킬 수 있고, 받은 응답 html파일에 데이터가 있기 때문에 SEO에 유리합니다.
const Users = ({ users, error }) => { return ( <section> <header> <h1>List of users</h1> </header> {error & <div>There was an error.</div>} {!error && users && ( <table> <thead> <tr> <th>Username</th> <th>Email</th> <th>Name</th> </tr> </thead> <tbody> {users.map((user, key) => ( <tr key={key}> <td>{user.username}</td> <td>{user.email}</td> <td>{user.name}</td> </tr> ))} </tbody> </table> )} </section> ); }; export async function getServerSideProps() { const res = await fetch("api request url"); const data = await res.json(); return { props: { data } }; } export default Users;

출처: https://www.patterns.dev/posts/server-side-rendering


Server Rendering with React.js

React는 SPA(Single Page Application), CSR 방식이지만, 부분적으로 서버에서 렌더링을 할 수 있도록 도와주는 라이브러리가 있습니다.

ReactDOMServer 객체를 통해 컴포넌트를 정적 마크업으로 렌더링할 수 있습니다. 대체로 Node 서버에서 사용됩니다.

//node server app.get("/", (req, res) => { const app = ReactDOMServer.renderToString(<App/>); });
//client ReactDOM.hydrate(<App />, document.getElementById("root"));

출처: https://www.patterns.dev/posts/server-side-rendering


reference

https://joshua1988.github.io/vue-camp/nuxt/ssr.html#서버-사이드-렌더링의-단점

https://darrengwon.tistory.com/938

https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props

https://www.patterns.dev/posts/server-side-rendering

https://ko.legacy.reactjs.org/docs/react-dom-server.html

https://ko.legacy.reactjs.org/docs/react-dom-client.html#hydrateroot