KEMBAR78
Hastening React SSR - Web Performance San Diego | PDF
HASTENING REACT SSR WITH
COMPONENT MEMOIZATION
AND TEMPLATIZATION
Increasing User Demand
www.radware.com
Web App Performance
•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
Server-Side Rendering (SSR)
•Better user experience of
the initial page load

•Better search engine ranking
SSR with React
Server-Side React
Bad User Experience!
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.
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
Server-Side React
0
325ms
650ms
975ms
1s 300ms
React React (best practices) mustache
https://github.com/ndreckshage/react-boston-ssr
• 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
React Rendering Lifecycle
getDefaultProps()
getInitialState()
componentWillMount()
render()
componentDidMount()
Create	Component	
Instance
Create	Transaction
Mount	Component	
(Gen	Markup)
Transaction.enqueue	
componentInstance
Transaction.dequeue
Mount	ComponentReact	EL	with	Props Markup
Given	a	set	of	properties,	the	markup	generated	is	always	the	same
Component	Cache
Double	Clicking	into	Mount	Component
Memoizing Components
The same “text” prop will always return
the same helloworld html string
class	HelloWorldComponent	extends	React.Component	{
	render()	{
			return	<div>Hello	{this.props.text}!</div>;
	}
}
When text is “World” the output is:
<div>Hello World!</div>
Memoizing Components
The same “text” prop will always return
the same helloworld html string
class	HelloWorldComponent	extends	React.Component	{
	render()	{
			return	<div>Hello	{this.props.text}!</div>;
	}
}
When text is “World” the output is:
<div>Hello World!</div>
var componentOptimization =
require("electrode-react-ssr-
optimization");
var componentOptimizationRef =
componentOptimization({
components: {
'HelloWorldComponent': {

keyAttrs: ["text"]
}
}
});
Memoizing Demo
Templatizing Componentsvar	React	=	require('react');
var	ProductView	=	React.createClass({
		render:	function()	{
				return	(
						<div	className="product">
								<img	src={this.props.product.image}/>
								<div	className="product-detail">
										<p	className="name">{this.props.product.name}</p>
										<p	className="description">{this.props.product.description}
</p>										<p	className="price">Price:	${this.props.product.price}</p>
										<button	type="button"	onClick={this.addToCart}	
disabled={this.props.inventory	>	0	?	''	:	'disabled'}>												Add	To	Cart
										</button>								
								</div>
						</div>
				);
		}
});
module.exports	=	ProductView;
Templatizing Componentsvar	React	=	require('react');
var	ProductView	=	React.createClass({
		render:	function()	{
				return	(
						<div	className="product">
								<img	src={this.props.product.image}/>
								<div	className="product-detail">
										<p	className="name">{this.props.product.name}</p>
										<p	className="description">{this.props.product.description}
</p>										<p	className="price">Price:	${this.props.product.price}</p>
										<button	type="button"	onClick={this.addToCart}	
disabled={this.props.inventory	>	0	?	''	:	'disabled'}>												Add	To	Cart
										</button>								
								</div>
						</div>
				);
		}
});
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.
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.
<div	className="product">
		<img	src=${product_image}/>
		<div	className="product-detail">
				<p	className="name">${product_name}</p>
				<p	className="description">${product_description}</p>
				<p	className="price">Price:	${selected_price}</p>
				<button	type="button"	onClick={this.addToCart}>
						Add	To	Cart
				</button>								
		</div>
</div>
Templatizing Componentsvar	React	=	require('react');
var	ProductView	=	React.createClass({
		render:	function()	{
				return	(
						<div	className="product">
								<img	src={this.props.product.image}/>
								<div	className="product-detail">
										<p	className="name">{this.props.product.name}</p>
										<p	className="description">{this.props.product.description}
</p>										<p	className="price">Price:	${this.props.product.price}</p>
										<button	type="button"	onClick={this.addToCart}	
disabled={this.props.inventory	>	0	?	''	:	'disabled'}>												Add	To	Cart
										</button>								
								</div>
						</div>
				);
		}
});
module.exports	=	ProductView;
var componentOptimization =
require("electrode-react-ssr-
optimization");
var componentOptimizationRef =
componentOptimization({
components: {
"ProductView": {
templateAttrs: ["product.image",

"product.name", 

"product.description", 

"product.price"]
},
}
});
Templatizing Componentsvar	React	=	require('react');
var	ProductView	=	React.createClass({
		render:	function()	{
				return	(
						<div	className="product">
								<img	src={this.props.product.image}/>
								<div	className="product-detail">
										<p	className="name">{this.props.product.name}</p>
										<p	className="description">{this.props.product.description}
</p>										<p	className="price">Price:	${this.props.product.price}</p>
										<button	type="button"	onClick={this.addToCart}	
disabled={this.props.inventory	>	0	?	''	:	'disabled'}>												{this.props.inventory	?	'Add	To	Cart'	:	'Sold	Out'}
										</button>								
								</div>
						</div>
				);
		}
});
module.exports	=	ProductView;
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	(
						<div	className="product">
								<img	src={this.props.product.image}/>
								<div	className="product-detail">
										<p	className="name">{this.props.product.name}</p>
										<p	className="description">{this.props.product.description}
</p>										<p	className="price">Price:	${this.props.product.price}</p>
										<button	type="button"	onClick={this.addToCart}	
disabled={this.props.inventory	>	0	?	''	:	'disabled'}>												{this.props.inventory	?	'Add	To	Cart'	:	'Sold	Out'}
										</button>								
								</div>
						</div>
				);
		}
});
module.exports	=	ProductView;
Templatizing Components
<div	className="product">
		<img	src=${product_image}/>
		<div	className="product-detail">
				<p	className="name">${product_name}</p>
				<p	className="description">${product_description}</p>
				<p	className="price">Price:	${selected_price}</p>
				<button	type="button"	onClick={this.addToCart}>
						Add	To	Cart
				</button>								
		</div>
</div>
<div	className="product">
		<img	src=${product_image}/>
		<div	className="product-detail">
				<p	className="name">${product_name}</p>
				<p	className="description">${product_description}</p>
				<p	className="price">Price:	${selected_price}</p>
				<button	type="button"	onClick={this.addToCart}>
						Sold	Out
				</button>								
		</div>
</div>
Cached Template 1 - Sold Out Cached Template 2 - Add To Cart
Templatizing Demo
green blocks indicating markup that was cached on the server
Server-Side React
CPU profile for one request
with rendering optimization
Thank You
https://github.com/walmartlabs/electrode-react-ssr-optimization

Hastening React SSR - Web Performance San Diego