react와 server side rendering

zmin·2022년 8월 8일
0

Client Side Rendering

한 번에 모든 파일을 불러와 파싱하고 렌더링한다.
일반적으로 html파일도 내부가 비어있어 로드된 javascript에 의해 채워지는 경우가 많다.(대표적인게 SPA, 리액트도 기본은 SPA이자 CSR이다)

상태가 변화하면 가상의 DOM트리를 만들어 변화된 노드만 갈아끼우는 형태로 UI가 업데이트 된다

이후 데이터를 위한 통신을 제외하면 화면에 인터페이스를 그리기위한 요청은 일반적으로 일어나지 않는다
→ 모두 브라우저에 있기 때문, 그래서 초기 렌더링이 좀 느리지만 이후 페이지 전환은 빠르다.

초반 로딩의 경우 관련 라이브러리를 사용해주면 유저가 느끼는 답답함을 어느정도 해소할 수 있지만 역시 가장 큰 단점은 SEO가 힘들다는 것이다.

서버 사이드 렌더링

Client side rendering과 달리 서버에서 렌더링 된 html을 넘겨줘서 화면에 나타내는 방식이다

html을 전달 받았을 때 이미 렌더링이 되어있는 상태라 화면에 이것이 나타나기까지의 시간은 CSR보다 짧을 수 있다. 물론 js를 다운받아서 html과 연결하기까지는 시간이 조금 걸려 잠시 상호작용이 안 될 수는 있지만.

하지만 요청이 왔을 때 html을 모두 렌더링 해서 넘겨주는 만큼 크롤링이 가능해져 SEO하기가 수월하다는 점이 있다.

그렇다고 SSR이 무조건 좋은 것은 아니다

html을 모두 렌더링해서 넘겨주기 때문에 페이지를 이동할 때 또 html을 받아오고 js를 연결해줘야해서 새로고침 및 로딩이 필요해지고 만약 이런 페이지 전환이 많아지게 되면 사용자는 답답함을 느낄 것이다.

하지만 또 서버로부터 받아야할 데이터양이 많아지면 CSR은

솔직히 이 두 가지의 장점만 뽑을 수 있다면 좋을 것 같은데..

리액트의 server side rendering

아주 좋은 next.js라는 프레임 워크가 있지만 리액트 공식 문서에 server관련 api들이 있는 것으로 봐선 리액트도 SSR을 제공할 기초 토대는 마련되어있는 것 같다. → next.js또한 이런 토대를 기반으로 만들어진 프레임워크일 것이라 추측한다.

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

renderToPipeableStream(element, option) ?

서버 단에서 html을 미리 렌더하여 클라이언트 측으로 보낼 수 있는 파이프(res)를 반환한다. 이렇게 만들어진 마크업에 hydrateRoot 를 이용하여 이벤트 핸들러를 부착할 수 있다.

이는 node js에 특화된 메소드(반환 값이 nodejs에서 실행할 수 이쓴ㄴ 것)라 웹 스트림이 있는 런타임환경에서는 아래 renderToReadableStream을 사용해야한다

renderToReadableStream(element)

readable stream을 가지는 resolves된 프로미스가 반환 → 이 스트림을 받아 client는 화면에 표시하게 됨 → stream API가 이를 받아 처리하게 됨

renderToStaticNodeStream(element)

html 문자열을 출력하는 readable stream을 반환! 그 문자열은 아래 renderToString과 같음. 다만 추가적인 어트리뷰트가 전부 삭제된 상태라 상호작용이 불가하다. 상호작용 하기 위해선 리액트가 접근할 수 있는 표시가 필요한데 이것들이 전부 삭제된 상태라 hydrate()가 안된다.

renderToString(element)

초기 html문자열을 만든다.

renderToStaticMarkup(element)

renderToString과 비슷하지만 element의 동작을 위해 부착되는 추가적인 어트리뷰트들이 모두 삭제된 html을 만든다. 그래서 아주 정적인 페이지를 만들때 유용

→ hydrate를 사용하고 싶다면 renderToString을 이용하는 것이 좋겠다.

근데 왜 나눠져있을까………….? 원래는 브라우저가 stream을 받아서 처리할 수 없어 html 문자열을 통해 ssr를 진행해왔는데 웹상에서 스트림처리 api가 등장하면서 해ㅐ당 타입(readable stream)의 처리가 가능해졌다. 그래서 원래는 서버상 처리를 위해서만 renderToPipeableStream() 같은 스트림 처리 메소드를 사용했고 클라이언트를 위해서는 renderToString이나 renderToStaticMarkup으로 문자열을 만들어 사용했었다. 하지만 현제 파이어폭스65+ 와 크롬42+ 에서만 fetch body객체를 스트림으로서 사용할 수 있다.

stream의 경우 파일을 쪼개서 흘려보낸다고 생각할 수 있는데 그래서 파일 전체를 준비시키고 날려야하는 것에 비해 첫 스타트가 빠르게 끊어진다.

react18의 streaming ssr과 suspence 활용하기

https://github.com/reactwg/react-18/discussions/37


추가로 Next.js는 SSR를 잘 활용할 수 있도록 도와주는 리액트 프레임워크

→ static generation 방식을 채택하고 있는데 이는 빌드 시점에 pre rendering 해둔 html들을 요청이 올때마다 재사용해서 보내주는 것이다. 그러니까 빌드 후 해당 페이지가 로드될 때마다 동일한 페이지를 보여줘야 할 때 적합한 것

→그렇다면 정적인 페이지만 가능한 것은 또 아니다. next.js의 장점이 html을 미리 렌더링하여 전달하고 그 내부에서 또 js를 사용하여 내용을 변경할 수 있기 때문에 CSR의 장점도 살릴 수 있다.

profile
308 Permanent Redirect

0개의 댓글