SlideShare a Scribd company logo
Async Server Rendering in
React+Redux
Jeremy Gayed
@tizmagik
Tech Lead & Senior Developer at NYTimes
Subscriber Experience Group
React all the things!
The Stack
● Node (Express)
● Babel
● React
● Redux (Flux)
● Webpack
● CSS Modules + SASS
● Mocha + Enzyme
● Nightwatch
Problem
When Server-Side Rendering, since
ReactDOMServer.renderToString()
is synchronous, how do you ensure that any asynchronous
data dependencies are ready/have resolved before
responding to the client?
All on the server
Long TTFB
All on the client
Poor SEO
Make the Server Aware
/* server.js */
const asyncRoutes = [...];
match({...}, (route) => {
if(asyncRoutes.contains(route)) {
// wait for data before res.end()
}
});
Inversion of Control
Routes Signal to Server
/* server.js */
if(route.isAsync()) {
// wait for data before res.end(...)
}
/* routes.jsx */
<Route path="/async/route"
component={asyncPage}
isAsync={true}
/>
Routes know too much
Individual
Components
Inform Server Ideal
But how to do so cleanly?
redux-taxi
Special Redux Middleware
+
Async Action Registration Decorator
=
Cleanly Decoupled Component-Driven Server-Side Rendering
Apply ReduxTaxi Middleware
export default function configureStore(initialState, instance) {
const middleware = applyMiddleware(
instance.reduxTaxi
? ReduxTaxiMiddleware(instance.reduxTaxi) // server context, reduxTaxi provided,
: syncHistory(instance.history), // client context, history provided.
// You do not have to use ReduxTaxi's PromiseMiddleware,
// but it's provided for convenience
PromiseMiddleware,
// Your other middleware...
thunk
);
return createStore(rootReducer, initialState, middleware);
}
What does an Async Action look like?
import {CHECK_PASSWORD_RESET_TOKEN} from 'actions/types';
import api from 'api/ForgotPasswordApi';
export function checkPasswordResetToken(token) {
return {
type: CHECK_PASSWORD_RESET_TOKEN,
promise: api.checkPasswordResetToken(token)
};
}
● ReduxTaxiMiddleware will collect the promise
● PromiseMiddleware will generate a sequence of FSA
Example: Component with Async Action
/* SomePage.jsx */
import SomePageActions from 'action/SomePageActions';
// usual redux store connection decorator
@connect(state => state.somePageState, SomePageActions)
export default class SomePage extends Component {
constructor(props, context) {
super(props, context);
// Dispatch async action
this.props.someAsyncAction(this.props.data);
}
// ... render() and other methods
}
Forgetting to Explicitly Register Async Actions
The async action SOME_ASYNC_ACTION was dispatched in a server context without
being explicitly registered.
This usually means an asynchronous action (an action that contains a Promise) was
dispatched in a component's instantiation.
If you DON'T want to delay pageload rendering on the server, consider moving the
dispatch to the React component's componentDidMount() lifecycle method (which
only executes in a client context).
If you DO want to delay the pageload rendering and wait for the action to resolve
(or reject) on the server, then you must explicitly register this action via the
@registerAsyncActions decorator.
Like so:
@registerAsyncActions(SOME_ASYNC_ACTION)
ReduxTaxi Example Usage
/* SomePage.jsx */
import SomePageActions from 'action/SomePageActions';
// usual redux store connection decorator
@connect(state => state.somePageState, SomePageActions)
export default class SomePage extends Component {
constructor(props, context) {
super(props, context);
// Dispatch async action
this.props.someAsyncAction(this.props.data);
}
// ... render() and other methods
}
import {SOME_ASYNC_ACTION} from 'action/types';
import {registerAsyncActions} from 'redux-taxi';
// explicitly register async action
@registerAsyncActions(SOME_ASYNC_ACTION)
No more error, the server knows to wait to render
/* server.js */
// Render once to instantiate all components (at the given route)
// and collect any promises that may be registered.
let content = ReactDOMServer.renderToString(initialComponent);
const allPromises = reduxTaxi.getAllPromises();
if (allPromises.length) {
// If we have some promises, we need to delay server rendering
Promise.all(allPromises).then(() => {
content = ReactDOMServer.renderToString(initialComponent);
res.end(content);
}).catch(() => {
// some error happened, respond with error page
});
} else {
// otherwise, we can respond immediately with our rendered app
res.end(content);
}
What does this buy you?
● Granular control over which components are rendered
server-side vs client-side
● Deliberate decisions around which components delay
server rendering
● Fail-early for unregistered actions
● All non-invasively
What’s next?
● Server rendering abstraction
● Integrations with other Promise-based middlewares
● Configurable Promise sniffing and collecting
● Potentially avoid double-rendering
Open Source
https://github.com/NYTimes/redux-taxi
redux-taxi
Thank you!
(P.S. We’re hiring!)
http://nytco.com/careers/technology
Jeremy Gayed
@tizmagik

More Related Content

What's hot

Monitoring Kubernetes with Prometheus
Monitoring Kubernetes with PrometheusMonitoring Kubernetes with Prometheus
Monitoring Kubernetes with Prometheus
Tobias Schmidt
 
Tomcat 6: Evolving our server
Tomcat 6: Evolving our serverTomcat 6: Evolving our server
Tomcat 6: Evolving our server
Jorge S Cruz Lambert
 
Deploying Rails Apps with Capistrano
Deploying Rails Apps with CapistranoDeploying Rails Apps with Capistrano
Deploying Rails Apps with Capistrano
Nyros Technologies
 
React and Flux life cycle with JSX, React Router and Jest Unit Testing
React and  Flux life cycle with JSX, React Router and Jest Unit TestingReact and  Flux life cycle with JSX, React Router and Jest Unit Testing
React and Flux life cycle with JSX, React Router and Jest Unit Testing
Eswara Kumar Palakollu
 
Reactive by example - at Reversim Summit 2015
Reactive by example - at Reversim Summit 2015Reactive by example - at Reversim Summit 2015
Reactive by example - at Reversim Summit 2015
Eran Harel
 
Funambol Automated Tests for SyncML Clients
Funambol Automated Tests for SyncML ClientsFunambol Automated Tests for SyncML Clients
Funambol Automated Tests for SyncML Clients
Funambol
 
Asynchronous handlers in asp.net
Asynchronous handlers in asp.netAsynchronous handlers in asp.net
Asynchronous handlers in asp.net
Abhishek Sur
 
AjaxAnywhere (Reloaded) library
AjaxAnywhere (Reloaded) libraryAjaxAnywhere (Reloaded) library
AjaxAnywhere (Reloaded) library
Angel Ruiz
 
Continous Delivery and Rails Upgrades
Continous Delivery and Rails UpgradesContinous Delivery and Rails Upgrades
Continous Delivery and Rails Upgrades
brianauton
 
Isomorphic server side rendering with Twig
Isomorphic server side rendering with TwigIsomorphic server side rendering with Twig
Isomorphic server side rendering with Twig
Jani Tarvainen
 
Airflow and supervisor
Airflow and supervisorAirflow and supervisor
Airflow and supervisor
Rafael Roman Otero
 
Continuous performance management with Gatling
Continuous performance management with GatlingContinuous performance management with Gatling
Continuous performance management with Gatling
Radoslaw Smilgin
 
Kafka monitoring and metrics
Kafka monitoring and metricsKafka monitoring and metrics
Kafka monitoring and metrics
Touraj Ebrahimi
 
Gatling @ Scala.Io 2013
Gatling @ Scala.Io 2013Gatling @ Scala.Io 2013
Gatling @ Scala.Io 2013
slandelle
 
Event sourcing with reactor and spring statemachine
Event sourcing with reactor and spring statemachineEvent sourcing with reactor and spring statemachine
Event sourcing with reactor and spring statemachine
Jimmy Lu
 
Performance tests with gatling
Performance tests with gatlingPerformance tests with gatling
Performance tests with gatling
SoftwareMill
 
Nextcon samza preso july - final
Nextcon samza preso   july - finalNextcon samza preso   july - final
Nextcon samza preso july - final
Yi Pan
 
Quartz to Implement Scheduling Service
Quartz to Implement Scheduling ServiceQuartz to Implement Scheduling Service
Quartz to Implement Scheduling Service
Akila Senevirathne
 
Leveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaLeveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS Lambda
Naresha K
 

What's hot (20)

Ruby и TestComplete
Ruby и TestCompleteRuby и TestComplete
Ruby и TestComplete
 
Monitoring Kubernetes with Prometheus
Monitoring Kubernetes with PrometheusMonitoring Kubernetes with Prometheus
Monitoring Kubernetes with Prometheus
 
Tomcat 6: Evolving our server
Tomcat 6: Evolving our serverTomcat 6: Evolving our server
Tomcat 6: Evolving our server
 
Deploying Rails Apps with Capistrano
Deploying Rails Apps with CapistranoDeploying Rails Apps with Capistrano
Deploying Rails Apps with Capistrano
 
React and Flux life cycle with JSX, React Router and Jest Unit Testing
React and  Flux life cycle with JSX, React Router and Jest Unit TestingReact and  Flux life cycle with JSX, React Router and Jest Unit Testing
React and Flux life cycle with JSX, React Router and Jest Unit Testing
 
Reactive by example - at Reversim Summit 2015
Reactive by example - at Reversim Summit 2015Reactive by example - at Reversim Summit 2015
Reactive by example - at Reversim Summit 2015
 
Funambol Automated Tests for SyncML Clients
Funambol Automated Tests for SyncML ClientsFunambol Automated Tests for SyncML Clients
Funambol Automated Tests for SyncML Clients
 
Asynchronous handlers in asp.net
Asynchronous handlers in asp.netAsynchronous handlers in asp.net
Asynchronous handlers in asp.net
 
AjaxAnywhere (Reloaded) library
AjaxAnywhere (Reloaded) libraryAjaxAnywhere (Reloaded) library
AjaxAnywhere (Reloaded) library
 
Continous Delivery and Rails Upgrades
Continous Delivery and Rails UpgradesContinous Delivery and Rails Upgrades
Continous Delivery and Rails Upgrades
 
Isomorphic server side rendering with Twig
Isomorphic server side rendering with TwigIsomorphic server side rendering with Twig
Isomorphic server side rendering with Twig
 
Airflow and supervisor
Airflow and supervisorAirflow and supervisor
Airflow and supervisor
 
Continuous performance management with Gatling
Continuous performance management with GatlingContinuous performance management with Gatling
Continuous performance management with Gatling
 
Kafka monitoring and metrics
Kafka monitoring and metricsKafka monitoring and metrics
Kafka monitoring and metrics
 
Gatling @ Scala.Io 2013
Gatling @ Scala.Io 2013Gatling @ Scala.Io 2013
Gatling @ Scala.Io 2013
 
Event sourcing with reactor and spring statemachine
Event sourcing with reactor and spring statemachineEvent sourcing with reactor and spring statemachine
Event sourcing with reactor and spring statemachine
 
Performance tests with gatling
Performance tests with gatlingPerformance tests with gatling
Performance tests with gatling
 
Nextcon samza preso july - final
Nextcon samza preso   july - finalNextcon samza preso   july - final
Nextcon samza preso july - final
 
Quartz to Implement Scheduling Service
Quartz to Implement Scheduling ServiceQuartz to Implement Scheduling Service
Quartz to Implement Scheduling Service
 
Leveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaLeveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS Lambda
 

Viewers also liked

React-redux server side rendering enchanted with varnish-cache for the fastes...
React-redux server side rendering enchanted with varnish-cache for the fastes...React-redux server side rendering enchanted with varnish-cache for the fastes...
React-redux server side rendering enchanted with varnish-cache for the fastes...
Grand Parade Poland
 
ProvJS: Six Months of ReactJS and Redux
ProvJS:  Six Months of ReactJS and ReduxProvJS:  Six Months of ReactJS and Redux
ProvJS: Six Months of ReactJS and Redux
Thom Nichols
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
Ben Lesh
 
RxJS + Redux + React = Amazing
RxJS + Redux + React = AmazingRxJS + Redux + React = Amazing
RxJS + Redux + React = Amazing
Jay Phelps
 
RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015
Ben Lesh
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
Ignacio Martín
 
reveal.js 3.0.0
reveal.js 3.0.0reveal.js 3.0.0
reveal.js 3.0.0
Hakim El Hattab
 

Viewers also liked (8)

React-redux server side rendering enchanted with varnish-cache for the fastes...
React-redux server side rendering enchanted with varnish-cache for the fastes...React-redux server side rendering enchanted with varnish-cache for the fastes...
React-redux server side rendering enchanted with varnish-cache for the fastes...
 
ProvJS: Six Months of ReactJS and Redux
ProvJS:  Six Months of ReactJS and ReduxProvJS:  Six Months of ReactJS and Redux
ProvJS: Six Months of ReactJS and Redux
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
 
RxJS + Redux + React = Amazing
RxJS + Redux + React = AmazingRxJS + Redux + React = Amazing
RxJS + Redux + React = Amazing
 
RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015
 
React js
React jsReact js
React js
 
Introduction to Redux
Introduction to ReduxIntroduction to Redux
Introduction to Redux
 
reveal.js 3.0.0
reveal.js 3.0.0reveal.js 3.0.0
reveal.js 3.0.0
 

Similar to Async Server Rendering in React+Redux at NYTimes (redux-taxi)

Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
Visual Engineering
 
React loadable
React loadableReact loadable
React loadable
George Bukhanov
 
Universal JS Applications with React
Universal JS Applications with ReactUniversal JS Applications with React
Universal JS Applications with React
Thanh Trần Trọng
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
Mihail Gaberov
 
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
OdessaJS Conf
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
Ignacio Martín
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript
名辰 洪
 
Секретный доклад о React Router - OdessaJS 2014
Секретный доклад о React Router - OdessaJS 2014Секретный доклад о React Router - OdessaJS 2014
Секретный доклад о React Router - OdessaJS 2014Andrey Listochkin
 
React for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence ConnectReact for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence Connect
Atlassian
 
WordCamp Montreal 2016 WP-API + React with server rendering
WordCamp Montreal 2016  WP-API + React with server renderingWordCamp Montreal 2016  WP-API + React with server rendering
WordCamp Montreal 2016 WP-API + React with server rendering
Ziad Saab
 
Node.js server-side rendering
Node.js server-side renderingNode.js server-side rendering
Node.js server-side rendering
The Software House
 
How to implement multiple layouts using React router V4.pptx
How to implement multiple layouts using React router V4.pptxHow to implement multiple layouts using React router V4.pptx
How to implement multiple layouts using React router V4.pptx
BOSC Tech Labs
 
Apache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextApache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's Next
Prateek Maheshwari
 
React JS .NET
React JS .NETReact JS .NET
React JS .NET
Jennifer Estrada
 
React lecture
React lectureReact lecture
React lecture
Christoffer Noring
 
Get your mobile app in production in 3 months: Native and Reactive Mobile Apps
Get your mobile app in production in 3 months: Native and Reactive Mobile AppsGet your mobile app in production in 3 months: Native and Reactive Mobile Apps
Get your mobile app in production in 3 months: Native and Reactive Mobile Apps
Ackee
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
Eliran Eliassy
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotXamarin
 
Service Worker Presentation
Service Worker PresentationService Worker Presentation
Service Worker PresentationKyle Dorman
 

Similar to Async Server Rendering in React+Redux at NYTimes (redux-taxi) (20)

Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
 
React loadable
React loadableReact loadable
React loadable
 
Universal JS Applications with React
Universal JS Applications with ReactUniversal JS Applications with React
Universal JS Applications with React
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
 
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
Universal JavaScript
Universal JavaScriptUniversal JavaScript
Universal JavaScript
 
Секретный доклад о React Router - OdessaJS 2014
Секретный доклад о React Router - OdessaJS 2014Секретный доклад о React Router - OdessaJS 2014
Секретный доклад о React Router - OdessaJS 2014
 
React for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence ConnectReact for Re-use: Creating UI Components with Confluence Connect
React for Re-use: Creating UI Components with Confluence Connect
 
WordCamp Montreal 2016 WP-API + React with server rendering
WordCamp Montreal 2016  WP-API + React with server renderingWordCamp Montreal 2016  WP-API + React with server rendering
WordCamp Montreal 2016 WP-API + React with server rendering
 
Node.js server-side rendering
Node.js server-side renderingNode.js server-side rendering
Node.js server-side rendering
 
How to implement multiple layouts using React router V4.pptx
How to implement multiple layouts using React router V4.pptxHow to implement multiple layouts using React router V4.pptx
How to implement multiple layouts using React router V4.pptx
 
Apache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's NextApache Samza 1.0 - What's New, What's Next
Apache Samza 1.0 - What's New, What's Next
 
React JS .NET
React JS .NETReact JS .NET
React JS .NET
 
Intro react js
Intro react jsIntro react js
Intro react js
 
React lecture
React lectureReact lecture
React lecture
 
Get your mobile app in production in 3 months: Native and Reactive Mobile Apps
Get your mobile app in production in 3 months: Native and Reactive Mobile AppsGet your mobile app in production in 3 months: Native and Reactive Mobile Apps
Get your mobile app in production in 3 months: Native and Reactive Mobile Apps
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
Advanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien PouliotAdvanced iOS Build Mechanics, Sebastien Pouliot
Advanced iOS Build Mechanics, Sebastien Pouliot
 
Service Worker Presentation
Service Worker PresentationService Worker Presentation
Service Worker Presentation
 

Recently uploaded

Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
Vlad Stirbu
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
UiPathCommunity
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
UiPathCommunity
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 

Recently uploaded (20)

Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 

Async Server Rendering in React+Redux at NYTimes (redux-taxi)

  • 1. Async Server Rendering in React+Redux Jeremy Gayed @tizmagik Tech Lead & Senior Developer at NYTimes
  • 3.
  • 4.
  • 5.
  • 6.
  • 7. React all the things!
  • 8. The Stack ● Node (Express) ● Babel ● React ● Redux (Flux) ● Webpack ● CSS Modules + SASS ● Mocha + Enzyme ● Nightwatch
  • 9. Problem When Server-Side Rendering, since ReactDOMServer.renderToString() is synchronous, how do you ensure that any asynchronous data dependencies are ready/have resolved before responding to the client?
  • 10. All on the server Long TTFB
  • 11. All on the client Poor SEO
  • 12. Make the Server Aware /* server.js */ const asyncRoutes = [...]; match({...}, (route) => { if(asyncRoutes.contains(route)) { // wait for data before res.end() } }); Inversion of Control
  • 13. Routes Signal to Server /* server.js */ if(route.isAsync()) { // wait for data before res.end(...) } /* routes.jsx */ <Route path="/async/route" component={asyncPage} isAsync={true} /> Routes know too much
  • 15. redux-taxi Special Redux Middleware + Async Action Registration Decorator = Cleanly Decoupled Component-Driven Server-Side Rendering
  • 16. Apply ReduxTaxi Middleware export default function configureStore(initialState, instance) { const middleware = applyMiddleware( instance.reduxTaxi ? ReduxTaxiMiddleware(instance.reduxTaxi) // server context, reduxTaxi provided, : syncHistory(instance.history), // client context, history provided. // You do not have to use ReduxTaxi's PromiseMiddleware, // but it's provided for convenience PromiseMiddleware, // Your other middleware... thunk ); return createStore(rootReducer, initialState, middleware); }
  • 17. What does an Async Action look like? import {CHECK_PASSWORD_RESET_TOKEN} from 'actions/types'; import api from 'api/ForgotPasswordApi'; export function checkPasswordResetToken(token) { return { type: CHECK_PASSWORD_RESET_TOKEN, promise: api.checkPasswordResetToken(token) }; } ● ReduxTaxiMiddleware will collect the promise ● PromiseMiddleware will generate a sequence of FSA
  • 18. Example: Component with Async Action /* SomePage.jsx */ import SomePageActions from 'action/SomePageActions'; // usual redux store connection decorator @connect(state => state.somePageState, SomePageActions) export default class SomePage extends Component { constructor(props, context) { super(props, context); // Dispatch async action this.props.someAsyncAction(this.props.data); } // ... render() and other methods }
  • 19. Forgetting to Explicitly Register Async Actions The async action SOME_ASYNC_ACTION was dispatched in a server context without being explicitly registered. This usually means an asynchronous action (an action that contains a Promise) was dispatched in a component's instantiation. If you DON'T want to delay pageload rendering on the server, consider moving the dispatch to the React component's componentDidMount() lifecycle method (which only executes in a client context). If you DO want to delay the pageload rendering and wait for the action to resolve (or reject) on the server, then you must explicitly register this action via the @registerAsyncActions decorator. Like so: @registerAsyncActions(SOME_ASYNC_ACTION)
  • 20. ReduxTaxi Example Usage /* SomePage.jsx */ import SomePageActions from 'action/SomePageActions'; // usual redux store connection decorator @connect(state => state.somePageState, SomePageActions) export default class SomePage extends Component { constructor(props, context) { super(props, context); // Dispatch async action this.props.someAsyncAction(this.props.data); } // ... render() and other methods } import {SOME_ASYNC_ACTION} from 'action/types'; import {registerAsyncActions} from 'redux-taxi'; // explicitly register async action @registerAsyncActions(SOME_ASYNC_ACTION)
  • 21. No more error, the server knows to wait to render /* server.js */ // Render once to instantiate all components (at the given route) // and collect any promises that may be registered. let content = ReactDOMServer.renderToString(initialComponent); const allPromises = reduxTaxi.getAllPromises(); if (allPromises.length) { // If we have some promises, we need to delay server rendering Promise.all(allPromises).then(() => { content = ReactDOMServer.renderToString(initialComponent); res.end(content); }).catch(() => { // some error happened, respond with error page }); } else { // otherwise, we can respond immediately with our rendered app res.end(content); }
  • 22. What does this buy you? ● Granular control over which components are rendered server-side vs client-side ● Deliberate decisions around which components delay server rendering ● Fail-early for unregistered actions ● All non-invasively
  • 23. What’s next? ● Server rendering abstraction ● Integrations with other Promise-based middlewares ● Configurable Promise sniffing and collecting ● Potentially avoid double-rendering
  • 25. Thank you! (P.S. We’re hiring!) http://nytco.com/careers/technology Jeremy Gayed @tizmagik