react

React는 User Interface(view)를 만드는 라이브러리입니다. Facebook에서 만들어서 Instagram에서 사용하고 있고 점점 많은 인기를 얻고 있는 라이브러리입니다.

React 홈페이지를 보면 대표적인 장점 3가지를 보여주고 있습니다.

  • JUST THE UI
    • MVC중 V(view)에 집중하고 있고 UI Component를 만드는데 집중한 라이브러리입니다. View 용도로 사용하기 때문에 AngularJS나 BackboneJS와도 조합하여 사용할 수 있습니다.
  • Virtual DOM
    • 내부적으로 가상의 DOM을 만들어 관리하고 최종적으로 화면에 렌더링 될때만 실제 DOM을 사용하기 때문에 속도가 빠릅니다. NodeJS를 이용한 서버렌더링을 빠르게 처리할 수 있습니다.
  • DATA FLOW
    • One way(단방향) 데이터 흐름을 지원하여 이해하기 쉽고 관리가 편하게 도와줍니다.

React를 최근 몇몇 프로젝트에 사용해 보면서 직접적으로 느낀점은 다음과 같습니다.

  • View에만 집중하고 있기 때문에 유명한 Javascript 프레임워크인 AngularJS와 비교하여 구조가 간단하고 학습이 빠른편입니다. 바로 프로젝트에 적용하기 쉽고 처음접하는 사람도 이해가 빠른편입니다.
  • Virtual DOM을 이용하여 속도를 빠르게 했다고 하는데 체감성능은 약간 빠른 느낌입니다. 모바일에서는 Javascript의 특성상 생각보다 성능이 좋지 않은 모습을 보여줍니다. 최신 아이폰6에서는 크게 문제가 되지 않았으나 안드로이드 폰에서는 초반에 렌더링이 약간 버벅이는 느낌이 있습니다. 이부분은 약간 실망..
  • React는 일반적으로 JSX를 이용하여 개발하고 JSX->Javascript로 변환하는 과정을 거치기 때문에 Webpack등의 Module Bundler를 사용합니다. 이때 Babel등의 라이브러리를 이용하여 ES6문법을 적용할 수 있고 webpack이나 browserify를 이용하면 npm 라이브러리를 바로 이용할 수 있어 ES6와 npm을 자연스럽게 지원하는 느낌입니다.
  • ReactJS는 서버렌더링을 지원하고 이부분이 굉장히 매력적으로 다가왔습니다. 서버렌더링을 이용하여 SEO(검색엔진 최적화)나 페이지 로딩 초반 화면 깜빡임 문제등을 쉽게 해결할 수 있었습니다. ReactJS.NET(.NET), react-php-v8js(php), react-rails(rails)와 같이 서버렌더링을 위한 라이브러리를 사용하여 복잡한 설정없이 바로 적용할 수 있습니다.

이번 포스트에서는 React의 여러 기능중 서버렌더링에 대해서 살펴보도록 하겠습니다.

Server Rendering이란?

ReactJS의 Server Rendering은 HTML Server Rendering을 의미합니다.
보통 자바스크립트 프레임웍이나 라이브러리를 이용하여 UI를 Rendering하면 페이지가 로드가 되고 자바스크립트를 이용하여 HTML을 만든다음 화면에 그리게 됩니다. 이 과정에서 화면 깜빡임(내용이 없다가 잠시후에 나타남)이 보이고 소스 보기를 하면 실제로 내용이 안보이기 때문에 SEO에서도 문제가 있습니다. Server Rendering은 Server에서 HTML을 그리기 때문에 화면 깜빡임 문제나 SEO 이슈가 발생하지 않습니다.

Server Rendering을 위한 method

ReactJS는 Server Rendering을 위해 renderToStringrenderToStaticMarkup method를 제공하고 있습니다.

renderToString

React.render를 통해 HTML을 Rendering할때 만드는 코드와 동일한 HTML코드를 생성합니다.

<div class="main-product-card-wrap" data-reactid=".1lwmz4w6hvk" data-react-checksum="-1444071738"><div class="purple-carousel-container" data-reactid=".1lwmz4w6hvk.0"><div class="purple-carousel" data-reactid=".1lwmz4w6hvk.0.0"><div class="product-card item" data-reactid=".1lwmz4w6hvk.0.0.0"> ...  

위와 같이 data-reactid attribute가 포함된 HTML을 생성합니다. 뭔가 불필요 보이는 속성이 붙은것 같지만 click이벤트가 있거나 동적으로 데이터가 바뀌는 경우에 반드시 필요한 속성들입니다. React를 단순 view template용도로 사용하는 경우가 아니라면 이 메소드를 이용해야 합니다.

이 메소드를 이용해서 서버에서 HTML을 Rendering하였다면 반드시 client에서도 React.render를 중복 수행해야합니다.

서버에서 이미 렌더링을 했는데 또 그리라구요???????

네, 맞습니다. 서버에서 만든 HTML은 이벤트등이 바인딩되지 않았기 때문에 React.render를 중복해서 사용해야 합니다. ReactJS는 똑똑하기 때문에 이미 rendering된 HTML을 다시 그리지 않고 이벤트만 바인딩하게 됩니다.

ReactJS가 똑똑하게 동작하는 이유는 data-react-checksum에 Rendering되는 HTML의 Checksum을 저장하고 변경여부를 판단하기 때문입니다. Date.now()등을 사용한다면 서버와 클리이언트의 rendering이 달라질수 있어 이런 경우는 다시 그리게 됩니다.

이러한 똑똑한 처리가 ReactJS를 이용하여 Server Rendering을 맘편히 쉽게 할 수 있도록 도와줍니다.

renderToStaticMarkup

react를 view template 엔진으로만 사용할 경우 react와 관련된 attribute를 추가하지 않고 필요한 HTML만 그리기 위해 사용하는 method입니다. 결과 코드가 깔끔하고 단순해집니다.

Server Rendering 방법

ReactJS를 Server에서 Rendering하는 방법은 크게 3가지가 있습니다.

  1. 서버가 NodeJS로 구성되어 있을 경우 바로 스크립트를 호출하는 방법
  2. NodeJS로 서버를 만들고 해당 서버에 Javascript를 동작시키는 방법
  3. V8엔진을 이용하여 NodeJS가 아닌 언어에서 Javascript를 작동하는 방법

첫번째 방법은 서버가 NodeJS일 경우 바로 React 코드를 실행할 수 있는 경우입니다. 바로 renderToString method를 수행하여 view에 그리면 됩니다.

두번째 방법은 서버가 NodeJS가 아닌경우 React 코드를 실행할 수 없기 때문에 React 코드만 실행하는 NodeJS를 이용한 서버를 띄우는 방법입니다. facebook에서 제공하는 샘플을 보면 이해가 쉬울 것 같습니다.

NodeJS 서버로 rendering을 위한 정보(module, props JSON)을 HTTP request하고 NodeJS 서버에서는 renderToString한 결과 string을 HTTP response하는 방법입니다.

서버를 하나 더 관리해야 하는 번거로움과 HTTP 통신으로 인한 overhead가 발생하여 좋지 않은 방법이라고 생각합니다.

마지막 방법은 V8엔진을 이용하는 것으로 대부분의 라이브러리에서 제공하는 방법입니다. V8엔진은 ruby, php, .NET등에서 바로 사용할 수 있으므로 별도의 NodeJS 서버를 띄우지 않고 javascript 코드를 수행하는 방법입니다.

대부분의 라이브러리는 비슷한 작업을 하며 react.js 소스와 추가적으로 개발한 component.js 소스를 V8엔진을 이용하여 수행하여 결과를 받아 렌더링합니다. V8엔진만 제대로 설치한다면 가장 손쉽게 구현할 수 있는 방법입니다.

결론

React Server Rendering은 서버와 클라이언트에서 동일한 코드를 가지고 작업할 수 있는 Isomorphic한 개발을 가능하게 해줍니다. 그리고 기존의 SPA(Single Page Applicatino)방식의 웹앱에서 나타나는 문제점을 쉽고 간단하게 해결해줍니다.
React를 사용한다면 Server Rendering 기능도 반드시 사용해보세요!



이 글이 도움이 되셨나요?

Feedly에서 Remotty 블로그 구독하기
페이스북에서 Remotty 구독하기