Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Performance and Scalability Art of Isomorphic React Applications

1,639 views

Published on

A couple weeks ago I have talked at React Amsterdam Meetup about Performance and Scalability of Isomorphic React Application.

Have a look at the video from this talk: https://www.youtube.com/watch?list=PLNBNS7NRGKMGLeJj3cuE4JDqJ0_9xAbZV&v=kI19MCP-wIE

Published in: Software
  • Be the first to comment

Performance and Scalability Art of Isomorphic React Applications

  1. 1. Isomorphic React Applications: Performance & Scalability Denis Izmaylov June 23, 2016
  2. 2. 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
  3. 3. • 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
  4. 4. Why should we stop developing classic Single Page Applications?
  5. 5. How does isomorphic applications affect your income?
  6. 6. What will you be doing this weekend?
  7. 7. Part 1 Architecture
  8. 8. Web became a serious environment
  9. 9. Art
 Web Development
 
 Science
  10. 10. How easy it was • Create a HTML file • Add some scripts • Submit to Production
  11. 11. How easy it was Server Browser 11
  12. 12. How easy it was Server Browser Does everything 12
  13. 13. How easy it was Server Browser - HTML - [CSS, JavaScript] Does everything 13
  14. 14. It worked
  15. 15. Segmentation
  16. 16. Segmentation Browser Server
  17. 17. Segmentation Front-end Back-end
  18. 18. Segmentation Front-end Back-end
  19. 19. Segmentation Front-end Back-end Changes are delivered with delay
  20. 20. Single Page
 Applications
 (SPA)
  21. 21. Single Page Application Server Browser 21
  22. 22. Single Page Application Server Browser Does the page exists?
 Do we need auth?
 Do we have access? 22
  23. 23. Single Page Application Server Browser Is the page exists?
 Do we need auth?
 Do we have access? - Tiny HTML, [CSS] - JavaScript bundle 23
  24. 24. 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
  25. 25. Single Page Application Benefits • Easy to start • <div id="root" /> • React, Redux • build JS bundle 25
  26. 26. Single Page Application Benefits • Easy to start • Rich features webpack, <div id=“root” />, React, Redux 26
  27. 27. Single Page Application Benefits • Easy to start • Rich features • Fast enhancement webpack, <div id=“root” />, React, Redux 27
  28. 28. Single Page Application Benefits • Easy to start • Rich features • Fast enhancement • Responsive UI webpack, <div id=“root” />, React, Redux 28
  29. 29. Single Page Application Benefits • Easy to start • Rich features • Fast enhancement • Responsive UI • Effortless caching webpack, <div id=“root” />, React, Redux 29
  30. 30. - Wow. Is it so ideal?
  31. 31. Single Page Application Costs • Long-time Start • JavaScript bundle up to 3-5 Mb • first request • execution • memory 31
  32. 32. Single Page Application Costs • Long-time Start • Expensive maintenance • side effects • memory leaks 1st request, CPU, mem 32
  33. 33. Single Page Application Costs • Long-time Start • Expensive maintenance • Empty page, one URL 1st request, CPU, mem side effects, memory leaks 33
  34. 34. 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
  35. 35. - Are they really “costs”?
  36. 36. Single Page Application for business 36
  37. 37. Single Page Application Costs • Long-Time Start for business reduced UX 37
  38. 38. Kissmetrics Blog
  39. 39. 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
  40. 40. Single Page Application Costs • Long-Time Start • Expensive Maintenance for business reduced UX risks 41
  41. 41. Single Page Application Costs • Long-Time Start • Expensive Maintenance • Empty Page for business reduced UX risks SEO problems 42
  42. 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
  43. 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
  44. 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
  45. 45. Single Page Application Costs for business reduced UX risks SEO problems Social Sharing problems lost audience 46 Losses
  46. 46. - What should we do?
 How do we solve this?
  47. 47. Take the best from both worlds
  48. 48. Isomorphic Applications
  49. 49. 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
  50. 50. 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
  51. 51. 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
  52. 52. Browser
 (Client) Isomorphic Applications Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc
  53. 53. Isomorphic Applications Browser
 (Client) Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc
  54. 54. Isomorphic Applications - HTML - [critical CSS] - … Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc Browser
 (Client)
  55. 55. Front-end Client Isomorphic Applications - HTML - [critical CSS] - JS Bundle Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc
  56. 56. Front-end Client Isomorphic Applications - HTML - [critical CSS] - JS Bundle Front-end Server
 Node.js
 Back-end Server
 
 API
 Database Java PHP
 etc
  57. 57. Front-end Client Isomorphic Applications Front-end Server • One execution environment • Shared codebase • Full control • Ecosystem • Microservices Architecture 58
  58. 58. Yesterday Front-end was only browser Front-end Back-end
  59. 59. Front-end Back-end Today Front-end is browser and server
  60. 60. - How can we do that?
  61. 61. Server-Side Rendering
 (SSR)
  62. 62. 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
  63. 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
  64. 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
  65. 65. 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
  66. 66. Part 2 Performance and Scalability
  67. 67. Functional Scalability
  68. 68. 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
  69. 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
  70. 70. Server-Side Rendering How to get async State:
 1. Manual for each page 2. Facebook Relay 3. Request Promises 71
  71. 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
  72. 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
  73. 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
  74. 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
  75. 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
  76. 76. Request Promises 77 Create Store Express Route Wait for resolving `fetchData` Render Components with Data Find Component for route
  77. 77. Request Promises 78 Static method in Components: class PartnersPage extends Component {
 static fetchData(getState, dispatch) {
 dispatch({
 type: PARTNERS_REQUEST,
 payload: fetch('/api/partners', …),
 })
 }
 // ….
  78. 78. Request Promises 79 Static method in Components: export default (
 <Route path='/' component={Layout}>
 <Route
 path='/partners'
 component={PartnersPage}
 />
 </Route>
 )
  79. 79. 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)
 })
  80. 80. Catching Request Promises Static method:
 1. react-router-redux 2. redux-router 81
  81. 81. Catching Request Promises What if you need computing for 
 some custom params
 to fetch data? 82
  82. 82. Catching Request Promises What if you like delegate
 decision about requests
 down to the tree? 83
  83. 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
  84. 84. 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
  85. 85. Performance
  86. 86. Performance Test stand: MacBook Pro 15” Retina (Early 2013) 2.4 GHz Intel Core i7 87
  87. 87. Performance Page size: 56 Kb
  88. 88. Performance Page size: 56 Kb
  89. 89. Performance Page size: 56 Kb
  90. 90. Performance Page size: 56 Kb
  91. 91. Performance Page size: 56 Kb
  92. 92. Performance Page size: 56 Kb
  93. 93. Performance We will test it with ab Apache HTTP server benchmarking tool
 
 https://httpd.apache.org/docs/2.4/ programs/ab.html 94
  94. 94. Performance Test with: ab -n 100 http://localhost:3000/profile
 95
  95. 95. Performance Test with: ab -n 100 http://localhost:3000/profile Executing… 96
  96. 96. Performance Test with: ab -n 100 http://localhost:3000/profile Executing… Time per request: 62 ms 97
  97. 97. Performance 62 ms
 Is it slow or fast? 98
  98. 98. Performance 62 ms
 Is it slow or fast?
 
 The same template in Handlebars:
 8 ms
 
 86% less 99
  99. 99. Performance 62 ms
 Is it slow or fast?
 
 The same template in Handlebars:
 8 ms
 
 86% less 100
  100. 100. Performance 1. Try to search in Google - nothing 2. Try to ask in Twitter - silence: 101
  101. 101. Performance Ok, what if we do that? NODE_ENV=production Executing… 102
  102. 102. Performance Ok, what if we do that? NODE_ENV=production Executing… Time per request: 38 ms
 (vs 62 ms)
 39% less 103
  103. 103. Performance Looks better
 
 104
  104. 104. Performance Looks better
 
 But it’s still not funny 105
  105. 105. Go ahead
  106. 106. GitHub issues
  107. 107. Performance • “Server rendering is slower with npm react”
 
 https://github.com/facebook/react/issues/812
 
 108
  108. 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
  109. 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
  110. 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
  111. 111. How does it influence
 results?
  112. 112. Performance Server rendering is slower with npm react react/dist/react.min.js Executing… 113
  113. 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
  114. 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
  115. 115. 0 17,5 35 52,5 70 38,25337,943 8,385 61,85 React SSR Handlebars production react.min.js Results
  116. 116. 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
  117. 117. Conclusion Always use
 NODE_ENV=production
  118. 118. Part 3 Advanced Solutions
  119. 119. Advanced Solutions 1. Precompilation + Cache 2. Rendering Separation 3. HTML Streaming 4. Facebook BigPipe 5. HAProxy 120
  120. 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
  121. 121. Rendering Separation 122
  122. 122. HTML Streaming 123Usually we do this
  123. 123. 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
  124. 124. Facebook BigPipe • Bundle a page during it’s loading • Assets are loading parallel • Resistants to errors
  125. 125. Facebook BigPipe • Bundle a page during it’s loading • Assets are loading parallel • Resistants to errors
  126. 126. Facebook BigPipe • Bundle a page during it’s loading • Assets is loading parallel • Resistants to errors
  127. 127. Facebook BigPipe • Bundle a page during it’s loading • Assets are loading parallel • Resistants to errors
  128. 128. Facebook BigPipe 129 https://www.facebook.com/notes/facebook- engineering/bigpipe-pipelining-web-pages-for- high-performance/389414033919/
  129. 129. HAProxy 130 • Multiple Node.js instance • Ask your DevOps engineer • Use CoreOS, Kubernetes or Mesosphere
  130. 130. Scale Cube 131 Monolith Infinite Scaling Y axis - functional decomposition X axis - horizontal duplication Zaxis-resources partitioning
  131. 131. X-Axis Scaling 132 Load Balancer Application Application Application By replicating
 the entire application
  132. 132. Y-Axis Scaling 133 Load Balancer Chat Catalog Orders /catalog /chat /orders By splitting
 the application
  133. 133. Z-Axis Scaling 134 Load Balancer [A - I] [J - R] [S - Z] /catalog/* /catalog/* /catalog/* By splitting
 the data
  134. 134. Z-Axis Scaling 135 Load Balancer Regular Premium Premium /catalog/* /catalog/* /catalog/* By splitting
 the resources
  135. 135. Epilogue
  136. 136. “Almost all algorithm problems could be solved by changing a data structure” “Changes is our work”,
 Jake Archibald, Google
  137. 137. Why should we stop developing classic Single Page Applications?
  138. 138. 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
  139. 139. Thank you Denis Izmaylov @DenisIzmaylov DenisIzmaylov www.startup-makers.com denis_izmaylov izmaylov.dm@gmail.com
  140. 140. 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
  141. 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
  142. 142. Secret Slide

×