Slide 1

Slide 1 text

HASTENING REACT SSR WITH COMPONENT MEMOIZATION AND TEMPLATIZATION

Slide 2

Slide 2 text

Increasing User Demand www.radware.com Web App Performance

Slide 3

Slide 3 text

•For every 1 second of improvement, experienced up to a 2% increase in conversions •For every 100 ms of improvement, grew incremental revenue by up to 1% Time is Money Source: http://www.globaldots.com/how-website-speed-affects-conversion-rates

Slide 4

Slide 4 text

Server-Side Rendering (SSR) •Better user experience of the initial page load
 •Better search engine ranking

Slide 5

Slide 5 text

SSR with React

Slide 6

Slide 6 text

Server-Side React Bad User Experience!

Slide 7

Slide 7 text

Server-Side React CPU profile for one request On large pages, renderToString(.) blocks nodeJS’s event-loop and starves out incoming requests to the server.

Slide 8

Slide 8 text

Server-Side React • Facebook: “Funny story about Server Rendering - it wasn’t actually designed that way.” (Sebastian Markbåge) • Facebook: “we don’t use it that heavily, which is why we haven’t really invested strongly in it.” (Sebastian Markbåge) React.js Conf 2015 
 Q&A with the team https://youtu.be/EPpkboSKvPI?t=7m48s

Slide 9

Slide 9 text

Server-Side React 0 325ms 650ms 975ms 1s 300ms React React (best practices) mustache https://github.com/ndreckshage/react-boston-ssr

Slide 10

Slide 10 text

• Looked at react-dom-stream and redfin/react-server to improve TTFB and ATF improvement • Challenges • Forks react and introduces new interfaces, i.e. not “React at heart” • Doesn't solve CPU total time Server-Side React ReactJS SF meetup in January 2016 https://github.com/aickin/react-dom-stream

Slide 11

Slide 11 text

React Rendering Lifecycle getDefaultProps() getInitialState() componentWillMount() render() componentDidMount() Create Component Instance Create Transaction Mount Component (Gen Markup) Transaction.enqueue componentInstance Transaction.dequeue

Slide 12

Slide 12 text

Mount Component React EL with Props Markup Given a set of properties, the markup generated is always the same Component Cache Double Clicking into Mount Component

Slide 13

Slide 13 text

Memoizing Components The same “text” prop will always return the same helloworld html string class HelloWorldComponent extends React.Component { render() { return
Hello {this.props.text}!
; } } When text is “World” the output is:
Hello World!

Slide 14

Slide 14 text

Memoizing Components The same “text” prop will always return the same helloworld html string class HelloWorldComponent extends React.Component { render() { return
Hello {this.props.text}!
; } } When text is “World” the output is:
Hello World!
var componentOptimization = require("electrode-react-ssr- optimization"); var componentOptimizationRef = componentOptimization({ components: { 'HelloWorldComponent': {
 keyAttrs: ["text"] } } });

Slide 15

Slide 15 text

Memoizing Demo

Slide 16

Slide 16 text

Templatizing Components var React = require('react'); var ProductView = React.createClass({ render: function() { return (

{this.props.product.name}

{this.props.product.description}

Price: ${this.props.product.price}

0 ? '' : 'disabled'}> Add To Cart
); } }); module.exports = ProductView;

Slide 17

Slide 17 text

Templatizing Components var React = require('react'); var ProductView = React.createClass({ render: function() { return (

{this.props.product.name}

{this.props.product.description}

Price: ${this.props.product.price}

0 ? '' : 'disabled'}> Add To Cart
); } }); module.exports = ProductView; • Dynamic props that would be different for each product.
 • Switch the corresponding props with template delimiters 
 (i.e. ${ prop_name }) during react component rendering cycle. • The template is then compiled, cached, executed and the markup is handed back to React.

Slide 18

Slide 18 text

Templatizing Components • Dynamic props that would be different for each product.
 • Switch the corresponding props with template delimiters 
 (i.e. ${ prop_name }) during react component rendering cycle. • The template is then compiled, cached, executed and the markup is handed back to React.

${product_name}

${product_description}

Price: ${selected_price}

Add To Cart

Slide 19

Slide 19 text

Templatizing Components var React = require('react'); var ProductView = React.createClass({ render: function() { return (

{this.props.product.name}

{this.props.product.description}

Price: ${this.props.product.price}

0 ? '' : 'disabled'}> Add To Cart
); } }); module.exports = ProductView; var componentOptimization = require("electrode-react-ssr- optimization"); var componentOptimizationRef = componentOptimization({ components: { "ProductView": { templateAttrs: ["product.image",
 "product.name", 
 "product.description", 
 "product.price"] }, } });

Slide 20

Slide 20 text

Templatizing Components var React = require('react'); var ProductView = React.createClass({ render: function() { return (

{this.props.product.name}

{this.props.product.description}

Price: ${this.props.product.price}

0 ? '' : 'disabled'}> {this.props.inventory ? 'Add To Cart' : 'Sold Out'}
); } }); module.exports = ProductView;

Slide 21

Slide 21 text

Templatizing Components var componentOptimization = require("electrode-react-ssr- optimization"); var componentOptimizationRef = componentOptimization({ components: { "ProductView": { templateAttrs: ["product.image",
 "product.name", 
 "product.description", 
 “product.price”], keyAttrs: ["product.inventory"] }, } }); var React = require('react'); var ProductView = React.createClass({ render: function() { return (

{this.props.product.name}

{this.props.product.description}

Price: ${this.props.product.price}

0 ? '' : 'disabled'}> {this.props.inventory ? 'Add To Cart' : 'Sold Out'}
); } }); module.exports = ProductView;

Slide 22

Slide 22 text

Templatizing Components

${product_name}

${product_description}

Price: ${selected_price}

Add To Cart

${product_name}

${product_description}

Price: ${selected_price}

Sold Out
Cached Template 1 - Sold Out Cached Template 2 - Add To Cart

Slide 23

Slide 23 text

Templatizing Demo

Slide 24

Slide 24 text

green blocks indicating markup that was cached on the server

Slide 25

Slide 25 text

Server-Side React CPU profile for one request with rendering optimization

Slide 26

Slide 26 text

Thank You https://github.com/walmartlabs/electrode-react-ssr-optimization