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.

Isomorphic React Applications: Performance And Scalability

4,840 views

Published on

Slides from my talk on React Meetup

Published in: Software

Isomorphic React Applications: Performance And Scalability

  1. 1. Isomorphic React Applications: Performance & Scalability Denis Izmaylov Nov 23, 2015
  2. 2. Denis Izmaylov • 15 years of Software and Web development experience • The last 5 years focused exclusively on Front-end, Node.js and architecture • Created 10+ projects, including Single Page Applications, high-load and React • Commiter to Redux, webpack and koa • Speaker at HighLoad++ 2015, MoscowJS • The author of “Application and Universal Components” and other articles , CEO
  3. 3. Why should we stop developing classic Single Page Applications?
  4. 4. How isomorphic applications affect your salary?
  5. 5. What will you do at this weekend?
  6. 6. You already know 1. React 14 2. webpack 3. ES6 4. Node.js 5. Express / koa 6. Isomorphic (Universal) apps 6
  7. 7. Part 1
  8. 8. Web became a giant
  9. 9. Art
 Web Development
 
 Science
  10. 10. Before it was easy • Create a page • Add some scripts • Submit to Production
  11. 11. Before it was easy Server Browser 11
  12. 12. Before it was easy Server Browser Does everything 12
  13. 13. Before it was easy Server Browser - HTML - [CSS, JavaScript] Does everything 13
  14. 14. It worked
  15. 15. Single Page
 Applications
 (SPA)
  16. 16. Single Page Application Server Browser 16
  17. 17. Single Page Application Server Browser Is the page exists?
 Do we need auth?
 Do we have access? 17
  18. 18. Single Page Application Server Browser Is the page exists?
 Do we need auth?
 Do we have access? - Tiny HTML, [CSS] - JavaScript bundle 18
  19. 19. Single Page Application Benefits • Easy to start • webpack • <div id=“root” /> • React, Redux • build 19
  20. 20. Single Page Application Benefits • Easy to start • Rich features webpack, <div id=“root” />, React, Redux 20
  21. 21. Single Page Application Benefits • Easy to start • Rich features • Fast enhancement webpack, <div id=“root” />, React, Redux 21
  22. 22. Single Page Application Benefits • Easy to start • Rich features • Fast enhancement • Responsive UI webpack, <div id=“root” />, React, Redux 22
  23. 23. Single Page Application Benefits • Easy to start • Rich features • Fast enhancement • Responsive UI • Useful caching webpack, <div id=“root” />, React, Redux 23
  24. 24. - Wow. Is it so ideal?
  25. 25. Single Page Application Flaws • Long-time Start • JavaScript bundle up to 3-5 Mb • first request • execution • memory 25
  26. 26. Single Page Application Flaws • Long-time Start • Expensive maintenance • side effects • memory leak 1st request, CPU, mem 26
  27. 27. Single Page Application Flaws • Long-time Start • Expensive maintenance • Empty page, one URL 1st request, CPU, mem side effects, memory leaks 27
  28. 28. Single Page Application Flaws • Long-time Start • Expensive maintenance • Empty page, one URL • Legacy Browsers 1st request, CPU, mem side effects, memory leaks 28
  29. 29. - Why is it “flaws”?
  30. 30. Single Page Application Flaws • Long-Time Start for business reduced UX 30
  31. 31. Single Page Application Flaws • Long-Time Start • Expensive Maintenance for business reduced UX risks 31
  32. 32. Single Page Application Flaws • Long-Time Start • Expensive Maintenance • Empty Page for business reduced UX risks SEO problems 32
  33. 33. Single Page Application Flaws • Long-Time Start • Expensive Maintenance • Empty Page • One URL for business reduced UX risks SEO problems SMM problems 33
  34. 34. Single Page Application Flaws • Long-Time Start • Expensive Maintenance • Empty Page • One URL • Legacy Browsers for business reduced UX risks SEO problems SMM problems lost audience 34
  35. 35. Single Page Application Flaws • Long-Time Start • Expensive Maintenance • Empty Page • One URL • Legacy Browsers for business reduced UX risks SEO problems SMM problems lost audience 35 Expenses
  36. 36. Single Page Application Flaws for business reduced UX risks SEO problems SMM problems lost audience 36 Expenses
  37. 37. - What to do?
  38. 38. Take the best from the both worlds
  39. 39. Isomorphic Applications
  40. 40. 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
  41. 41. Templates Stylesheets Locale (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
  42. 42. Browser Isomorphic Applications Front-end Server Back-end Server
 
 Database Java
 etc
  43. 43. Browser Isomorphic Applications Front-end Server Back-end Server
 
 Database Java
 etc
  44. 44. Browser Isomorphic Applications Front-end Server Back-end Server
 
 Database Java
 etc - HTML - [critical CSS] - …
  45. 45. Front-end Client Isomorphic Applications Front-end Server Back-end Server
 
 Database Java
 etc - HTML - [critical CSS] - JS Bundle
  46. 46. Front-end Client Isomorphic Applications Front-end Server Back-end Server
 
 Database Java
 etc - HTML - [critical CSS] - JS Bundle
  47. 47. Front-end Client Isomorphic Applications Front-end Server • One execution environment
 • Shared codebase
 • Full control
 • Ecosystem 47
  48. 48. - How can we do that?
  49. 49. Server-Side Rendering
 (SSR)
  50. 50. Server-Side Rendering • Build HTML on Front-end Server • Render page in user browser immediately, before it loads JavaScript • When JavaScript will be loaded,
 React will add event handlers only • It’s very fast 50
  51. 51. Server-Side Rendering Example code for Server-Side: import ReactDOMServer from 'react-dom/server';
 import Application from './components/application';
 
 const body = ReactDOMServer.renderToString(
 <Application />
 ); 51
  52. 52. 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. This way keeps all JavaScript features 52
  53. 53. Part 2
  54. 54. Performance And Scalability
  55. 55. Scalability
  56. 56. Functional Scalability
  57. 57. 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} />
 ); 57
  58. 58. 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? 58
  59. 59. Server-Side Rendering How to get asynchronous State:
 1. Manual for each page 2. Facebook Relay 3. redux-catch-promise 59
  60. 60. Asynchronous State Manual for each page: • Define which data we have to load for each page • Load this data and prepare State • ReactDOMServer.renderToString() 60
  61. 61. Asynchronous State Facebook Relay: 1. The framework for building data-driven React applications 2. Declarative. Colocation. Mutations. 3. https://github.com/facebook/relay/ issues/136 4. 1Q2016 61
  62. 62. Asynchronous State redux-catch-promise: • Redux - state container для React • Redux: the best for isomorphic apps, MoscowJS 25
 https://youtu.be/Uyk_8WWna6s • redux-catch-promise is middleware for Redux 62
  63. 63. Asynchronous State redux-catch-promise: 1. Attach a callback to catch Promise-actions 2. Render the component 3. At the component - create a request to DB (or other data source) and dispatch a Promise of that 4. Collect all promises and wait until they will be finished 5. Render component with data 63
  64. 64. Asynchronous State redux-catch-promise: 1. Example and source code:
 https://github.com/DenisIzmaylov/ redux-catch-promise 2. Installation: npm install redux-catch-promise 64
  65. 65. Performance
  66. 66. Performance Test stand: MacBook Pro 15” Retina (Early 2013) 2.4 GHz Intel Core i7 66
  67. 67. Performance Page size: 56 238 bytes
  68. 68. Performance Page size: 56 238 bytes
  69. 69. Performance Page size: 56 238 bytes
  70. 70. Performance Page size: 56 238 bytes
  71. 71. Performance Page size: 56 238 bytes
  72. 72. Performance Page size: 56 238 bytes
  73. 73. Performance Test with: ab -n 100 http://localhost:3000/profile
 73
  74. 74. Performance Test with: ab -n 100 http://localhost:3000/profile Executing… 74
  75. 75. Performance Test with: ab -n 100 http://localhost:3000/profile Executing… Time per request: 61.850 ms 75
  76. 76. Performance 61.850 ms
 Is it slow or fast? 76
  77. 77. Performance 61.850 ms
 Is it slow or fast?
 
 The same template in Handlebars:
 8.385 ms
 
 86% less 77
  78. 78. Performance 61.850 ms
 Is it slow or fast?
 
 The same template in Handlebars:
 8.385 ms
 
 86% less 78
  79. 79. Performance 1. Try to search in Google - nothing 2. Try to ask in Twitter - silence: 79
  80. 80. Performance Ok, what if we do that? NODE_ENV=production Executing… 80
  81. 81. Performance Ok, what if we do that? NODE_ENV=production Executing… Time per request: 37.943 ms
 (vs 61.850 ms)
 39% less 81
  82. 82. Performance Looks better.
 
 But it’s still not funny. 82
  83. 83. Go ahead
  84. 84. GitHub issues
  85. 85. Performance • “Server rendering is slower with npm react”
 
 https://github.com/facebook/react/issues/812
 
 85
  86. 86. Performance • “Server rendering is slower with npm react”
 
 https://github.com/facebook/react/issues/812
 
 Solution:
 use directly react/dist/react.min.js 86
  87. 87. 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'); }
 87
  88. 88. 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'); }
 88
  89. 89. How can it influence
 on results?
  90. 90. Performance Server rendering is slower with npm react react/dist/react.min.js Executing… 90
  91. 91. 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 91
  92. 92. 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 92
  93. 93. 0 17,5 35 52,5 70 38,25337,943 8,385 61,85 React SSR Handlebars production react.min.js Results
  94. 94. 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
  95. 95. Part 3
  96. 96. Advanced
 Solutions
  97. 97. Advanced Solutions 1. Precompilation + Cache 2. Rendering Separation 3. Progressive Rendering 4. Facebook BigPipe 5. HAProxy 97
  98. 98. Precompilation + Cache • UI = f(state) • f = React Component • state = path + [actions] + …
 1. Simple solution: redis 2. Deferred server-side rendering:
 redis + kue.js + workers 98
  99. 99. Rendering Separation 99
  100. 100. Progressive Rendering 100
  101. 101. Progressive Rendering • 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://github.com/aickin/react-dom-stream 101
  102. 102. Facebook BigPipe • Bundle a page during it’s loading • Assets is loading parallel • Resistants to errors
  103. 103. Facebook BigPipe • Bundle a page during it’s loading • Assets is loading parallel • Resistants to errors
  104. 104. Facebook BigPipe • Bundle a page during it’s loading • Assets is loading parallel • Resistants to errors
  105. 105. Facebook BigPipe 105
  106. 106. HAProxy • Multiple Node.js instance • Ask your DevOps engineer 106
  107. 107. Epilogue
  108. 108. Recommendations • Find and join local JavaScript communities • Improve your English skills • Read original articles and technical blogs (Facebook, AirBnB, Netflix, etc) • Join and integrate Twitter and GitHub to your life 108
  109. 109. 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/ 109
  110. 110. 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 110
  111. 111. Quotes “Almost algorithm problems could be solved by changing a data structure” “Changes is our work”,
 Jake Archibald, Google
  112. 112. Why should we stop developing classic Single Page Applications?
  113. 113. izmaylov.dm@gmail.com Submit short information about you
  114. 114. Thank you Denis Izmaylov @DenisIzmaylov https://github.com/DenisIzmaylov http://startup-makers.com denis_izmaylov izmaylov.dm@gmail.com
  115. 115. Secret Slide

×