Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Bring your web application architecture to the ...
Search
Bastian Hofmann
June 11, 2015
Programming
240
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Bring your web application architecture to the next level with React.JS
Bastian Hofmann
June 11, 2015
More Decks by Bastian Hofmann
See All by Bastian Hofmann
Monitoring in Kubernetes with Prometheus and Grafana
bastianhofmann
0
380
Creating a fast Kubernetes Development Workflow
bastianhofmann
0
150
Highly available cross-region deployments with Kubernetes
bastianhofmann
1
190
From source to Kubernetes in 30 minutes
bastianhofmann
0
200
Introduction to Kubernetes
bastianhofmann
1
140
CI/CD with Kubernetes
bastianhofmann
0
260
Creating a fast Kubernetes Development Workflow
bastianhofmann
1
300
Deploying your first Micro-Service application to Kubernetes
bastianhofmann
2
220
Creating a fast Kubernetes Development Workflow
bastianhofmann
0
290
Other Decks in Programming
See All in Programming
GemmaをJevのように使ってみる / Use Gemma like Jev
kishida
5
790
Compiling a real-world CLI tool to native with Static Hermes
tmikov2023
0
120
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
290
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
28
32k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
190
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
2
680
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
750
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
220
當我們開始不讀 Code - AI Agent 時代,Code Review 與 Clean Code 還剩下什麼?
jame2408
1
220
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
5
5.1k
Rでドレミ/Do-Re-Mi_with_R
florets1
0
130
【加筆修正版】Laravel のアプリケーションをどこにデプロイするか #phpcon_ehime
akase244
0
150
Featured
See All Featured
Practical Orchestrator
shlominoach
192
12k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
710
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.2k
Utilizing Notion as your number one productivity tool
mfonobong
4
620
30 Presentation Tips
portentint
PRO
1
430
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
How to make the Groovebox
asonas
2
2.5k
Odyssey Design
rkendrick25
PRO
2
870
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Mobile First: as difficult as doing things right
swwweet
225
10k
Large-scale JavaScript Application Architecture
addyosmani
516
110k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.4k
Transcript
Bring your web application to the next level with React.JS
@BastianHofmann
Let's talk about...
Application architecture
Code and component re-use
Rapid Development
Handling large code-bases
With React.js
With small and independent components
webserver HTML browser JS controller
webserver HTML browser JS Ajax controller
webserver HTML browser JS Ajax controller
de duplication ode duplication code duplication code duplication code duplication
code duplication code duplication code duplication code duplication code duplication code duplication code duplication code duplication code duplicatio code duplicat code duplic code dup code du code cod co co
So?
A few words about me
None
None
http://speakerdeck.com/u/bastianhofmann
Application architecture
many roads
None
status quo
webserver HTML browser JS Ajax controller
webserver loadbalancer pgsql memcached mongodb services
webserver
None
MVC
Duplication and only some Code re- use
We can do better
Small components over big controllers
None
None
None
None
None
None
None
None
Self contained
Can be used everywhere
JS is part of the component
CSS can be part of the component
http://facebook.github.io/react/
JavaScript UI Library
Many small, self contained, reusable components
var HelloMessage = React.createClass( { render: function () { return
<div>Hello {this.props.name}</div>; } } ); React.render(<HelloMessage name="John" />, mountNode);
var Timer = React.createClass({ getInitialState: function () { return {secs:
0}; }, tick: function () { this.setState({secs: this.state.secs + 1}); }, componentDidMount: function () { this.interval = setInterval(this.tick, 1000); }, componentWillUnmount: function () { clearInterval(this.interval); }, render: function () { return (<div> Seconds Elapsed: {this.state.secs}</div> ); } }); React.render(<Timer />, mountNode);
var TodoList = React.createClass( { render: function () { var
createItem = function (itemText) { return <li>{itemText}</li>; }; return ( <ul> {this.props.items.map(createItem)} </ul> ); } } );
var TodoApp = React.createClass({ render: function () { return (
<div> <h3>TODO</h3> <TodoList items={this.props.items} /> </div> ); } });
Getting the data in there
PHP Backend JSON React Frontend
PHP Backend JSON React Frontend
PHP Backend JSON React Frontend
PHP Backend JSON React Frontend
var TodoApp = React.createClass({ getInitialState: function () { return {items:
[…]}; }, render: function () { return ( <div> <h3>TODO</h3> <TodoList items={this.state.items} /> </div> ); } });
Problematic
Remember
Self-contained
Reusable
PHP Backend JSON React Frontend
PHP Backend JSON React Frontend
PHP Backend JSON React Frontend
Overfetching
Underfetching
Solutions
Flux Datastores
PHP Backend React Frontend Datastores
GraphQL https://gist.github.com/wincent/598fa75e22bdfa44cf47
Requirements
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Institution Menu
React Frontend
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu PHP
Backend Request Response Institution
LeftColumn Image Menu React Frontend
LeftColumn Image Menu Request Response PHP Backend
Remember: self contained
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Account
Account Account Account Account Publication1 Publication2 Publication3 Institution
Do not fetch data directly
Sssssssllllooooowww
Require stuff
http://www.infoq.com/presentations/Evolution-of-Code- Design-at-Facebook/
None
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations
Widget Widget Widget Widget Preparer Fetch Requirements Resolver Resolver Services
Connector Interfaces Connector Implementations
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations Batch requirements and pass them to resolvers
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations Call Services as effective as possible (Multi-GET,...)
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations Attach fetched data to Requirements and pass them back to the preparer
Widget Widget Widget Widget Preparer Resolver Resolver Services Connector Interfaces
Connector Implementations Distribute fetched data to the widgets that required it
public function collect() { return [ new EntityRequirement( 'account', Account::class,
['id' => $this->request->get('id')] ), ]; }
Request Cache
Multi-GET
Futures
Data dependencies within a widget
public function collect() { yield [ new EntityRequirement( 'account', Account::class,
['id' => $this->request->get('id')] ), ]; yield [ new ServiceRequirement( 'scienceDisciplines', AccountService::class, 'getScienceDisciplines', ['account' => $this->account] ) ]; }
Assembling the tree
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu PHP
Backend Request Response Institution
Widget Requirement
class PublicationKeywordSearch { public $publications; public $publicationListItems = [];
public function collect() { yield [ serviceRequirement( 'publications', PublicationService::getCall()->getByKeywords( ['virology', 'cancer'], 10, 0 ) ) ]; foreach ($this->publications as $publication) { yield new WidgetRequirement( 'publicationListItems', PublicationItem::CLASS, [ 'publicationId' => $publication->getId() ] ); } } }
class PublicationItem { public $publicationId; public $publication; public
function collect() { yield new RequestDataRequirement('publicationId'); yield [ new EntityRequirement( 'publication', Publication::class, ['id' => $this->publicationId] ) ]; } }
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Getting the data to React.js
public function getData() { return [ 'key' => 'value', 'other'
=> 'data', 'number' => 42, 'subComponent' => $this->subComponent, 'someArray' => [1, 2, 3], 'subComponentList' => [ $this->items[0], $this->items[1] ] ]; }
{ "ParentComponent-1234": { "component": "ParentComponent.jsx", "id": "ParentComponent-1234", "data": { "key":
"value", "other": "data", "number": 42, "subComponent": "SubComponent", "someArray": [1, 2, 3], "subComponentList": [ "ListItem-444", "ListItem-555"] } }, "SubComponent": { "component": "SubComponent.jsx", "id": "SubComponent", "data": { "boolValue": true } }, "ListItem-444": { "component": "ListItem", "id": "ListItem-444", "data": { "title": "444s title“ } }, "ListItem-555": { "component": "ListItem", "id": "ListItem-555", "data": { "title": "555s title" } } }
var React = require('react'); var SubComponent = require('SubComponent'); var ListItem
= require('ListItem'); module.exports = React.createClass( { displayName: 'ParentComponent', render: function () { var items = []; for (var key in this.props.subComponentList) { if (this.props.subComponentList.hasOwnProperty(key)) { items.push( <li> <ListItem componentId={this.props.subComponentList[key]}/> </li> ); } } return ( <div className="{this.props.key}"> <h1>{this.props.other} Hello PHP {this.props.number}</h1> <SubComponent componentId={this.props.subComponent} /> <ul>{items}</ul> </div> ); } } );
var React = require('react'); module.exports = React.createClass( { displayName:
'ListItem', render: function () { return ( <div> {this.props.title} </div> ); } } );
Server side rendering
SEO
Better user experience
Several approaches
NodeJS service
Request HTML Preparer nodeJS service PHP process Data JSON Rendered
HTML string React Hogan
Bundling
http://webpack.github.io/
None
Whoa
This looks awfully complicated to debug
None
None
Benefits
Enables developers to only focus on their components
Rapid prototyping
Easier Refactoring
Easy re-using of components
Error Handling
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu EXCEPTION
Institution
Profile Publications Publication Publication Publication LeftColumn Image Menu Institution
Experiments (A/B Testing)
Feature toggles
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu Institution
Profile Publications Publication Publication Publication AboutMeNew LeftColumn Image Menu Institution
Caching of Components
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu <esi:include
src="..." /> Institution
Load components asynchronously
Profile Publications Publication Publication Publication AboutMe LeftColumn Image Menu <div
id="placeholder"></div> <script>loadWidget('/aboutMe', function(w) { w.render({ replace : '#placeholder' }); })</script> Institution
Conclusion?
Think about your architecture
Refactor and make it better continuously
Frontend and backend are part of the same application
Don't rewrite your whole codebase in one go
http://twitter.com/BastianHofmann http://lanyrd.com/people/BastianHofmann http://speakerdeck.com/u/bastianhofmann
[email protected]