Isomorphic React Applications: Performance & Scalability Denis Izmaylov June 23, 2016
Denis Izmaylov • 16 years of Software and Web development experience • The last 6 years focused exclusively
 on Front-end and Web • 15+ projects, including SPA,
 high-load and React • Commits to Redux, webpack and koa • Speaker at HighLoad++ 2015,
 AgileDays 2016, RIT 2016, DevConf 2016 • Regular speaker at MoscowJS meetups • “Application and Universal Components” and other articles
• We develop web,
 mobile and DevOps projects for
 our customers • We use right and most efficient solutions • We have more than 20 talented developers
 in the team
Why should we stop developing classic Single Page Applications?
How does isomorphic applications affect your income?
What will you be doing this weekend?
Part 1 Architecture
Web became a serious environment
Art
 Web Development
 
 Science
How easy it was • Create a HTML file • Add some scripts • Submit to Production
How easy it was Server Browser 11
How easy it was Server Browser Does everything 12
How easy it was Server Browser - HTML - [CSS, JavaScript] Does everything 13
It worked
Segmentation
Segmentation Browser Server
Segmentation Front-end Back-end
Segmentation Front-end Back-end
Segmentation Front-end Back-end Changes are delivered with delay
Single Page
 Applications
 (SPA)
Single Page Application Server Browser 21
Single Page Application Server Browser Does the page exists?
 Do we need auth?
 Do we have access? 22
Single Page Application Server Browser Is the page exists?
 Do we need auth?
 Do we have access? - Tiny HTML, [CSS] - JavaScript bundle 23
Single Page Application Server Browser Is the page exists?
 Do we need auth?
 Do we have access? - Tiny HTML, [CSS] - JavaScript bundle 24 - AJAX - iframes
Single Page Application Benefits • Easy to start • <div id="root" /> • React, Redux • build JS bundle 25
Single Page Application Benefits • Easy to start • Rich features webpack, <div id=“root” />, React, Redux 26
Single Page Application Benefits • Easy to start • Rich features • Fast enhancement webpack, <div id=“root” />, React, Redux 27
Single Page Application Benefits • Easy to start • Rich features • Fast enhancement • Responsive UI webpack, <div id=“root” />, React, Redux 28
Single Page Application Benefits • Easy to start • Rich features • Fast enhancement • Responsive UI • Effortless caching webpack, <div id=“root” />, React, Redux 29
- Wow. Is it so ideal?
Single Page Application Costs • Long-time Start • JavaScript bundle up to 3-5 Mb • first request • execution • memory 31
Single Page Application Costs • Long-time Start • Expensive maintenance • side effects • memory leaks 1st request, CPU, mem 32
Single Page Application Costs • Long-time Start • Expensive maintenance • Empty page, one URL 1st request, CPU, mem side effects, memory leaks 33
Single Page Application Costs • Long-time Start • Expensive maintenance • Empty page, one URL • Hard to support Legacy Browsers 1st request, CPU, mem side effects, memory leaks 34
- Are they really “costs”?
Single Page Application for business 36
Single Page Application Costs • Long-Time Start for business reduced UX 37
Kissmetrics Blog
Kissmetrics Blog “…If e-commerce sites is making $100,000 per day,
 a one second page delay
 could potentially cost you
 $2.5 million in lost sales
 every year…” 39
Single Page Application Costs • Long-Time Start • Expensive Maintenance for business reduced UX risks 41
Single Page Application Costs • Long-Time Start • Expensive Maintenance • Empty Page for business reduced UX risks SEO problems 42
Single Page Application Costs • Long-Time Start • Expensive Maintenance • Empty Page • One URL for business reduced UX risks SEO problems Social Sharing problems 43
Single Page Application Costs • Long-Time Start • Expensive Maintenance • Empty Page • One URL • Legacy Browsers for business reduced UX risks SEO problems Social Sharing problems lost audience 44
Single Page Application Costs • Long-Time Start • Expensive Maintenance • Empty Page • One URL • Legacy Browsers for business reduced UX risks SEO problems Social Sharing problems lost audience 45 Losses
Single Page Application Costs for business reduced UX risks SEO problems Social Sharing problems lost audience 46 Losses
- What should we do?
 How do we solve this?
Take the best from both worlds
Isomorphic Applications
Isomorphic Applications By isomorphic we mean that any given line of code (with notable exceptions) can execute both on the client and the server. 
 Charlie Robbins,
 18 Oct 2011
Templates Stylesheets i18n Configuration Routes Access Rules Models Schemas Validation Services Isomorphic Applications server.jsNode.js worker.js client.jsBrowser admin.js Business Logic Components API interfaces Actions, Reducers Static Files, etc
Templates Stylesheets i18n Configuration Routes Access Rules Models Schemas Validation Services Isomorphic Applications server.jsNode.js worker.js client.jsBrowser admin.js Business Logic Components API interfaces Actions, Reducers Static Files, etc + React Native
Browser
 (Client) Isomorphic Applications Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc
Isomorphic Applications Browser
 (Client) Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc
Isomorphic Applications - HTML - [critical CSS] - … Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc Browser
 (Client)
Front-end Client Isomorphic Applications - HTML - [critical CSS] - JS Bundle Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc
Front-end Client Isomorphic Applications - HTML - [critical CSS] - JS Bundle Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc
Front-end Client Isomorphic Applications Front-end Server • One execution environment • Shared codebase • Full control • Ecosystem • Microservices Architecture 58
Yesterday Front-end was only browser Front-end Back-end
Front-end Back-end Today Front-end is browser and server
- How can we do that?
Server-Side Rendering
 (SSR)
Server-Side Rendering • Build HTML on Front-end (Node.js) Server • Render Page in your browser immediately, before it loads JavaScript • When JavaScript will be loaded,
 React just add event handlers only • It works very fast 63
Server-Side Rendering Example code for Server-Side: import ReactDOMServer from 'react-dom/server';
 import Application from './components/application';
 
 const body = ReactDOMServer.renderToString(
 <Application />
 ); 64
Server-Side Rendering Example code for Server-Side: import ReactDOMServer from 'react-dom/server';
 import Application from './components/application';
 
 const body = ReactDOMServer.renderToString(
 <Application />
 ); 65 Render React Component
 to plain string
Server-Side Rendering 1. Visitors see a page immediately 2. No additional requests to load data 3. The page could work even without JS 4. Full URL-navigation 5. Meta-tags for SEO and SMM 6. Better security 66
Part 2 Performance and Scalability
Functional Scalability
Server-Side Rendering That’s super when we have all data for response:
 import ReactDOMServer from 'react-dom/server';
 import Application from './components/application';
 
 const initialState = { siteName: 'Startup Makers' };
 const body = ReactDOMServer.renderToString(
 <Application state={initialState} />
 ); 69
Server-Side Rendering That’s super when we have all data for response:
 import ReactDOMServer from 'react-dom/server';
 import Application from './components/application';
 
 const initialState = { siteName: 'Startup Makers' };
 const body = ReactDOMServer.renderToString(
 <Application state={initialState} />
 ); What if we have to load it async? 70
Server-Side Rendering How to get async State:
 1. Manual for each page 2. Facebook Relay 3. Request Promises 71
Asynchronous State Manual for each page: • Define which data you have to load for each page • Load this data and prepare Initial State • ReactDOMServer.renderToString() 72
Asynchronous State Facebook Relay:
 1. The framework for building data-driven React applications 2. Declarative data fetching 3. https://github.com/denvned/isomorphic- relay 73
Asynchronous State Request Promises:
 • Redux - state container for React • Redux is close to be standard for React apps • Redux: the best for isomorphic apps, MoscowJS 25
 https://youtu.be/Uyk_8WWna6s • We will use Redux for next steps 74
Request Promises Two ways:
 1. Call static methods for each main Component before render 2. Pre-render Elements Tree without data,
 push requests promises in constructors and re-render Elements with data 75
Request Promises Handle static methods with React Router
 1. Create Redux store 2. Link Redux Store with Router middleware 3. Dispatch MATCH action for
 requested location 4. Add response handler for `store.router.then()` 5. Router middleware lookup for static `fetchData` method in component of Route 76
Request Promises 77 Create Store Express Route Wait for resolving `fetchData` Render Components with Data Find Component for route
Request Promises 78 Static method in Components: class PartnersPage extends Component {
 static fetchData(getState, dispatch) {
 dispatch({
 type: PARTNERS_REQUEST,
 payload: fetch('/api/partners', …),
 })
 }
 // ….
Request Promises 79 Static method in Components: export default (
 <Route path='/' component={Layout}>
 <Route
 path='/partners'
 component={PartnersPage}
 />
 </Route>
 )
Request Promises 80 Static method in Components: const store = createStore()
 store.getState().router.then((err, redirect, props) => {
 const content = renderToString(
 <Provider store={store}>
 <RouterContext {…props} />
 </Provider>
 )
 res.send(content)
 })
Catching Request Promises Static method:
 1. react-router-redux 2. redux-router 81
Catching Request Promises What if you need computing for 
 some custom params
 to fetch data? 82
Catching Request Promises What if you like delegate
 decision about requests
 down to the tree? 83
redux-catch-promise:
 1. Render the Elements Tree without Data 2. Collect all promises 3. Wait until they will be resolved 4. Re-render the Elements Tree with fetched data 5. Send rendered HTML to client 84 Catching Request Promises
redux-catch-promise:
 1. Example and source code:
 https://github.com/DenisIzmaylov/ redux-catch-promise 2. Installation: npm install redux-catch-promise 85 Catching Request Promises
Performance
Performance Test stand: MacBook Pro 15” Retina (Early 2013) 2.4 GHz Intel Core i7 87
Performance Page size: 56 Kb
Performance Page size: 56 Kb
Performance Page size: 56 Kb
Performance Page size: 56 Kb
Performance Page size: 56 Kb
Performance Page size: 56 Kb
Performance We will test it with ab Apache HTTP server benchmarking tool
 
 https://httpd.apache.org/docs/2.4/ programs/ab.html 94
Performance Test with: ab -n 100 http://localhost:3000/profile
 95
Performance Test with: ab -n 100 http://localhost:3000/profile Executing… 96
Performance Test with: ab -n 100 http://localhost:3000/profile Executing… Time per request: 62 ms 97
Performance 62 ms
 Is it slow or fast? 98
Performance 62 ms
 Is it slow or fast?
 
 The same template in Handlebars:
 8 ms
 
 86% less 99
Performance 62 ms
 Is it slow or fast?
 
 The same template in Handlebars:
 8 ms
 
 86% less 100
Performance 1. Try to search in Google - nothing 2. Try to ask in Twitter - silence: 101
Performance Ok, what if we do that? NODE_ENV=production Executing… 102
Performance Ok, what if we do that? NODE_ENV=production Executing… Time per request: 38 ms
 (vs 62 ms)
 39% less 103
Performance Looks better
 
 104
Performance Looks better
 
 But it’s still not funny 105
Go ahead
GitHub issues
Performance • “Server rendering is slower with npm react”
 
 https://github.com/facebook/react/issues/812
 
 108
Performance • “Server rendering is slower with npm react”
 
 https://github.com/facebook/react/issues/812
 
 Solution:
 use directly react/dist/react.min.js 109
Performance Create node_modules/react.js:
 
 if (process.env.NODE_ENV === 'production') { module.exports = require('react/dist/react.min.js'); } else { module.exports = require('react/dist/react.js'); }
 110
Performance Create node_modules/react.js:
 
 if (process.env.NODE_ENV === 'production') { module.exports = require('react/dist/react.min.js'); } else { module.exports = require('react/dist/react.js'); }
 111
How does it influence
 results?
Performance Server rendering is slower with npm react react/dist/react.min.js Executing… 113
Performance Server rendering is slower with npm react react/dist/react.min.js Executing… Time per request: 38.253 ms
 (vs 37.943 ms)
 0.08% more 114
Performance Server rendering is slower with npm react react/dist/react.min.js Executing… Time per request: 38.253 ms
 (vs 37.943 ms)
 0.08% more FAILED 115
0 17,5 35 52,5 70 38,25337,943 8,385 61,85 React SSR Handlebars production react.min.js Results
0 17,5 35 52,5 70 38,25337,943 8,385 61,85 React SSR Handlebars production react.min.js Results NODE_ENV=production
 39% less
Conclusion Always use
 NODE_ENV=production
Part 3 Advanced Solutions
Advanced Solutions 1. Precompilation + Cache 2. Rendering Separation 3. HTML Streaming 4. Facebook BigPipe 5. HAProxy 120
Precompilation + Cache • UI = f(state) • f = React Component • state = path + [actions] + …
 1. Simple solution: redis 2. Deferred server-side rendering:
 redis + kue.js + workers 121
Rendering Separation 122
HTML Streaming 123Usually we do this
HTML Streaming • React DOM Stream • Flushing the Document Early • “Streams make this library as much as 47% faster in sending down a full page than ReactDOM.renderToString” • Target - 108KB page on Heroku • Time To First Byte (TTFB) - 55% faster • https://www.youtube.com/watch?v=PnpfGy7q96U • https://github.com/aickin/react-dom-stream 124
Facebook BigPipe • Bundle a page during it’s loading • Assets are loading parallel • Resistants to errors
Facebook BigPipe • Bundle a page during it’s loading • Assets are loading parallel • Resistants to errors
Facebook BigPipe • Bundle a page during it’s loading • Assets is loading parallel • Resistants to errors
Facebook BigPipe • Bundle a page during it’s loading • Assets are loading parallel • Resistants to errors
Facebook BigPipe 129 https://www.facebook.com/notes/facebook- engineering/bigpipe-pipelining-web-pages-for- high-performance/389414033919/
HAProxy 130 • Multiple Node.js instance • Ask your DevOps engineer • Use CoreOS, Kubernetes or Mesosphere
Scale Cube 131 Monolith Infinite Scaling Y axis - functional decomposition X axis - horizontal duplication Zaxis-resources partitioning
X-Axis Scaling 132 Load Balancer Application Application Application By replicating
 the entire application
Y-Axis Scaling 133 Load Balancer Chat Catalog Orders /catalog /chat /orders By splitting
 the application
Z-Axis Scaling 134 Load Balancer [A - I] [J - R] [S - Z] /catalog/* /catalog/* /catalog/* By splitting
 the data
Z-Axis Scaling 135 Load Balancer Regular Premium Premium /catalog/* /catalog/* /catalog/* By splitting
 the resources
Epilogue
“Almost all algorithm problems could be solved by changing a data structure” “Changes is our work”,
 Jake Archibald, Google
Why should we stop developing classic Single Page Applications?
Takeaways 1. Classic SPA is very expensive for business 2. Isomorphic Applications provides better UX, SEO, Social Marketing, reduce risks and costs 3. Shared codebase and one ecosystem is good investment to high efficiency development 4. SSR performance is not good 5. We know a lot of advanced solutions to improve it very well 6. Microservices architecture is best solution where we will have Front-end Server just as Render service
Thank you Denis Izmaylov @DenisIzmaylov DenisIzmaylov www.startup-makers.com denis_izmaylov izmaylov.dm@gmail.com
Useful Links 1. Supercharging page load (100 Days of Google Dev)
 https://youtu.be/d5_6yHixpsQ 2. Making Netflix.com Faster
 http://techblog.netflix.com/2015/08/making-netflixcom- faster.html 3. New technologies for the new LinkedIn home page
 https://engineering.linkedin.com/frontend/new-technologies- new-linkedin-home-page 4. Improving performance on Twitter.com
 https://blog.twitter.com/2012/improving-performance-on- twittercom 5. Scaling Isomorphic Javascript Code
 http://blog.nodejitsu.com/scaling-isomorphic-javascript-code/ 141
Useful Links 6. From AngularJS to React: The Isomorphic Way
 https://blog.risingstack.com/from-angularjs-to-react-the- isomorphic-way/ 7. Isomorphic JavaScript: The Future of Web Apps
 http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/ 8. React server side rendering performance
 http://www.slideshare.net/nickdreckshage/react-meetup 9. The Lost Art of Progressive HTML Rendering
 http://blog.codinghorror.com/the-lost-art-of-progressive-html- rendering/ 10. Extract and inline Critical Path CSS in HTML pages
 https://github.com/addyosmani/critical 142
Secret Slide

Performance and Scalability Art of Isomorphic React Applications