ReactJS 서버 측 렌더링 대 클라이언트 측 렌더링


120

방금 ReactJS를 연구하기 시작했는데 이것이 페이지를 렌더링하는 두 가지 방법 인 서버 측과 클라이언트 측을 제공한다는 것을 발견했습니다. 그러나 함께 사용하는 방법을 이해할 수 없습니다. 응용 프로그램을 빌드하는 두 가지 방법입니까, 아니면 함께 사용할 수 있습니까?

함께 사용할 수 있다면 어떻게해야합니까? 서버 측과 클라이언트 측에서 동일한 요소를 복제해야합니까? 또는 이미 미리 렌더링 된 서버 측에 연결하지 않고 서버에 애플리케이션의 정적 부분을 구축하고 클라이언트 측에 동적 부분을 구축 할 수 있습니까?


1
짧은 대답, 아니요-분리하고 정적 html을 보내고 클라이언트 렌더링에서 완전히 변경할 수 있습니다. 내 대답에 세부 사항을 추가했습니다.
Kira

답변:


108

주어진 웹 사이트 / 웹 응용 프로그램에 대해 클라이언트 측 , 서버 측 또는 둘 다를 사용할 수 있습니다 .

고객 입장에서

여기에서 브라우저에서 ReactJS를 완전히 실행하고 있습니다. 이것은 가장 간단한 설정이며 대부분의 예제 ( http://reactjs.org에 있는 예제 포함)를 포함합니다 . 서버에서 렌더링 한 초기 HTML은 자리 표시 자이며 모든 스크립트가로드되면 전체 UI가 브라우저에서 렌더링됩니다.

서버 측

여기서 ReactJS를 서버 측 템플릿 엔진 (예 : jade, 핸들 바 등)으로 생각하십시오. 서버에서 렌더링 한 HTML에는 UI가 있어야하며 스크립트가로드 될 때까지 기다리지 않습니다. 귀하의 페이지는 검색 엔진에서 색인을 생성 할 수 있습니다 (JavaScript를 실행하지 않는 경우).

UI가 서버에서 렌더링되기 때문에 이벤트 핸들러가 작동하지 않으며 상호 작용이 없습니다 (정적 페이지가 있음).

양자 모두

여기에서 초기 렌더링은 서버에 있습니다. 따라서 브라우저에서 수신 한 HTML에는 UI가 있어야합니다. 스크립트가로드되면 가상 DOM이 다시 한 번 다시 렌더링되어 구성 요소의 이벤트 핸들러를 설정합니다.

여기 props에서 서버에서 렌더링 할 때 사용한 것과 동일한 가상 DOM (루트 ReactJS 구성 요소)을 다시 렌더링해야합니다. 그렇지 않으면 ReactJS는 서버 측과 클라이언트 측 가상 DOM이 일치하지 않는다고 불평합니다.

ReactJS는 re-render간에 가상 DOM을 비교하므로 실제 DOM은 변경되지 않습니다. 이벤트 핸들러 만 실제 DOM 요소에 바인딩됩니다.


1
그래서 "둘 다"의 경우 서버 렌더링을 위해 동일한 코드를 두 번 작성해야합니다. 하나는이 DOM을 클라이언트에서 재현하는 것입니까? 맞습니까?
Simcha

10
동일한 코드를 두 번 실행 해야합니다 . 서버에서 한 번, 클라이언트에서 한 번. 그러나이를 고려하려면 구성 요소를 작성해야합니다. 예를 들어 componentWillMount()클라이언트와 서버를 모두 실행하므로 에서 비동기 데이터를 가져 오지 않아야 합니다. 또한 동일한 출력을 얻으려면 서버에서 데이터를 미리 가져오고 클라이언트에서 초기 렌더링에 사용할 수 있도록 만드는 전략이 필요합니다.
Jonny Buchanan 2014

3
실행중인 코드가 서버 측에 있는지 클라이언트 측에 있는지 확인한 typeof window == "undefined"다음 그에 따라 데이터를 가져올 수도 있습니다.
Gautham Badhrinathan 2014

구현에 맞는 예제에 대한 링크가 있습니까?
Sawtaytoes

1
@IanW 일반적으로이 경우 서버가 반환하는 HTML은 매우 "베어 본 (bare bones)"이며, 단순히 JavaScript와 스타일을 가져오고 <div>React가 작성할를 포함합니다 .
Matt Holland

48

이미지 출처 : Walmart Labs 엔지니어링 블로그

SSR

CSR

NB : SSR (서버 측 렌더링), CSR (클라이언트 측 렌더링).

주요 차이점은 SSR을 사용하면 클라이언트 브라우저에 대한 서버 응답에 렌더링 할 페이지의 HTML이 포함된다는 것입니다. SSR을 사용하면 페이지가 더 빨리 렌더링된다는 점에 유의하는 것도 중요합니다. JS 파일이 다운로드되고 브라우저가 React를 실행할 때까지 페이지는 사용자 상호 작용을 위해 준비되지 않습니다.

한 가지 단점은 SSR TTFB (Time to First Byte)가 약간 더 길 수 있다는 것입니다. 당연히 서버가 HTML 문서를 만드는 데 시간이 걸리기 때문에 서버 응답 크기가 증가합니다.


4

나는 실제로 동일한 연구에 대해 꽤 궁금해하고 있으며 찾고있는 답변이 의견에 주어졌지만 더 눈에 띄어 야한다고 생각 하므로이 게시물을 작성하고 있습니다. 구조적으로 적어도 의심스러운 솔루션을 찾을 때 더 나은 방법).

두 가지 방법모두 염두에두고 구성 요소를 작성해야 하므로 기본적으로 if스위치를 어디에나 두어 클라이언트에 있는지 서버에 있는지 확인한 다음 DB 쿼리 (또는 서버에 적절한 것) 또는 REST 호출 ( 고객). 그런 다음 데이터를 생성하고 클라이언트에 노출하는 엔드 포인트를 작성해야합니다.

다시 한 번 더 깨끗한 솔루션에 대해 배우게되어 기쁩니다.


2

응용 프로그램을 빌드하는 두 가지 방법입니까, 아니면 함께 사용할 수 있습니까?

함께 사용할 수 있습니다.

함께 사용할 수 있다면 어떻게해야합니까? 서버 측과 클라이언트 측에서 동일한 요소를 복제해야합니까? 또는 이미 미리 렌더링 된 서버 측에 연결하지 않고 서버에 애플리케이션의 정적 부분을 구축하고 클라이언트 측에 동적 부분을 구축 할 수 있습니까?

리플 로우 및 리 페인트 작업을 방지하고 깜박임 / 깜박임을 줄이려면 동일한 레이아웃을 렌더링하는 것이 좋습니다. 페이지가 더 부드러워집니다. 그러나 제한이 아닙니다. SSR html ( Electrode 가 응답 시간을 줄이기 위해 하거나 CSR (클라이언트 측 렌더링)에 의해 덮어 쓰여지는 정적 html을 보낼 수 있습니다.

SSR로 시작하는 경우 간단하게 시작하는 것이 좋습니다. SSR은 매우 빠르게 복잡해질 수 있습니다. 서버에서 html을 빌드한다는 것은 창, 문서 (클라이언트에 있음)와 같은 객체에 대한 액세스 권한을 잃고 비동기 작업을 통합하는 기능 (즉시 사용 가능)을 잃고 일반적으로 코드 SSR과 호환되도록 많은 코드 편집을 수행하는 것을 의미합니다 ( bundle.js를 포장하려면 webpack을 사용해야하므로). CSS 가져 오기와 같은 것들은 갑자기 당신을 물기 시작합니다 (웹팩이없는 기본 React 앱에서는 그렇지 않습니다).

SSR의 일반적인 패턴은 다음과 같습니다. 요청을 처리하는 Express 서버 :

const app = Express();
const port = 8092;

// This is fired every time the server side receives a request
app.use(handleRender);
function handleRender(req, res) {
    const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
    console.log('fullUrl: ', fullUrl);
    console.log('req.url: ', req.url);

    // Create a new Redux store instance
    const store = createStore(reducerFn);

    const urlToRender = req.url;
    // Render the component to a string
    const html = renderToString(
        <Provider store={store}>
            <StaticRouter location={urlToRender} context={{}}>
                {routes}
            </StaticRouter>
        </Provider>
    );
    const helmet = Helmet.renderStatic();

    // Grab the initial state from our Redux store
    const preloadedState = store.getState();

    // Send the rendered page back to the client
    res.send(renderFullPage(helmet, html, preloadedState));
}

SSR로 시작하는 사람들에게 내 제안은 정적 HTML을 제공하는 것입니다. CSR SPA 앱을 실행하여 정적 HTML을 가져올 수 있습니다.

document.getElementById('root').innerHTML

잊지 마세요. SSR을 사용하는 유일한 이유는 다음과 같습니다.

  1. SEO
  2. 더 빠른로드 (저는 이것을 할인합니다)

해킹 : https://medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.