Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React server-side render nightmare gone

wwwy3y3
November 07, 2017

React server-side render nightmare gone

React server-side render nightmare gone

wwwy3y3

November 07, 2017
Tweet

More Decks by wwwy3y3

Other Decks in Technology

Transcript

  1. React SSR is HARD! • Some modules need some hack

    during SSR (some may use window, document…) • Some modules require you to use additional API during SSR (react-router, react-redux) • Only nodejs support react SSR, so we have to separate a SSR server
  2. Basic Solution • Webpack build commonJS, require on nodeJS Server

    • When request come in, ReactDOM.renderToString(commonJSApp) • insert HTML to Template
  3. Basic Solution cons • Server need to install all client-side

    dependencies • ReactDOMServer.renderToString() can monopolize the CPU, block node’s event-loop
  4. Prior art • nextJS • Complete Framework for server-render •

    Too many limitation (on webpack config, css module and router) • Too much work on migration
  5. What’s the problem • Some modules require additional hack and

    API usage (react-router StaticRouter, react-redux Provider…) • We have to install client-side modules on server (react-router, react-redux) just for SSR • To avoid event loop blocking, we need to separate a SSR server…
  6. How can we make it better? • Performance: No More

    Render On Server • Flexible: customize own SSR process • Easy: should not be pain to integrate • Automation: Automatic transpilation and bundling
  7. Tradeoff - with Redux • Coren prerender pages with initial

    state offline, so server can simply serve the result • When it comes to dynamic data, server can put data it fetched from DB to Redux preloadedState Coren generate Server Response + https://github.com/Canner/coren
  8. Redux state Coren generate Server Response + https://github.com/Canner/coren State State

    { video: null, isFetching: true, fetched: false } { video: <video>, isFetching: false, fetched: true }
  9. Redux state Coren generate Server Response + https://github.com/Canner/coren State State

    { product: { name: “vacummer”, desc: “cool”, price: 120, count: null } } { product: { name: “vacummer”, desc: “cool”, price: 120, count: 20 } } count: 20
  10. Benefits • Doesn’t require client-side library on server • NO

    Render, NO Blocking event-loop on server • Still save round-trip time by putting data to preloadedState https://github.com/Canner/coren
  11. Example1 - head tags • How to add Headers? •

    How to know what routes to render? Example: https://github.com/Canner/coren-example
  12. Example2 - static data • How to add static data

    to preloadedState? • Data not going to change for long time could be fetched at first (e.g. 2011 NBA Finals scores) Example: https://github.com/Canner/coren-example
  13. Example3 - ReactRouter & Redux • If you’re using react-router

    & redux, you will need to wrap component with <StaticRouter> & <Provider store={store}> • Coren use @reactRouterRedux decorator Example: https://github.com/Canner/coren-example
  14. Example4 - server response • Server respond coren result with

    data Example: https://github.com/Canner/coren-example • Server respond coren result without data
  15. Coren decorators • Coren SSR process consists of several lifecycles

    that decorators can make use of. • for example, using react-router + react-redux + react-intl require you to wrap component this way.
  16. Coren decorators • There’s a lifecycle called wrapSSR, so decorator

    can tell coren what components are required to wrap outside. Return Lifecycle
  17. Coren decorators • Coren decorators return a lifecycle object, controlling

    what to do during SSR. SSR Process Collect all routes from @route decorator Loop routes setOptions Lifecycle wrapSSR appendToHead appendToBody 1. setOptions: set variables that will be shared among decorators 2. wrapSSR: wrap components outside 3. appendToHead: append elements to <head> 4. appendToBody: append elements to <body>
  18. Overall Process 1. Add decorators to components 2. setup coren.config.js

    & webpack 3. replace your template file, write res.sendCoren() 4. run 5. deploy generated files to server $ coren build
  19. Coren result • Prerender basic HTML with static data •

    => avoid first blank page • server respond HTML with dynamic data • => save API round-trip time • easy integrate with webpack, babel and add assets to header • => save develop time • no more import React, ReactDOM… on server
  20. Roadmap • Streaming Response • More use case • Support

    more backend languages support (java, python…)
  21. powered by Canner, give us a star if you like

    it! Thank you. Q&A https://github.com/Canner/coren