SlideShare a Scribd company logo
1 of 43
Download to read offline
High Performance Web UI's with
Om and React
LambdaJam - Brisbane, 2014
Leonardo Borges
@leonardo_borges
www.leonardoborges.com
www.thoughtworks.com
About
‣ ThoughtWorker
‣ Functional Programming & Clojure
advocate
‣ Founder of the Sydney Clojure User
Group
‣ Currently writing “Clojure Reactive
Programming”
Functional Programming
is on the rise
And that makes us happy
However if you do client-side web
development, you’re out of luck
Because Javascript…
[1,3,5].map(parseInt);!
// [1, NaN, NaN]!
There are options
Today we’ll see one of them:
Clojurescript
What we’ll see
‣ An Overview of React and how it enables fast rendering
‣ Meet Om, a ClojureScript interface to React
‣ Boosting React’s rendering performance with immutable data structures
‣ A simple demo featuring “data binding” and undo functionality
React
‣ Created by Facebook for building user interfaces
‣ The V in MVC
‣ Self-contained components
‣ Doesn’t make assumptions about your stack - can be used with anything
Self-contained components
‣ React combines display logic and DOM generation
‣ Components are themselves loosely coupled
‣ The whole app is re-rendered on every update
‣ Virtual DOM
‣ Efficient diff algorithm
Efficient diff algorithm
‣ Creates a virtual version of the DOM
‣ As the application state changes new DOM trees are generated
‣ React diffs the trees and computes the minimal set of changes
‣ Finally it applies the changes to the real DOM
A simple React component
var HelloMessage = React.createClass({!
displayName: 'HelloMessage',!
render: function() {!
return React.DOM.div(null, "Hello ", this.props.name);!
}!
});!
!
React.renderComponent(!
HelloMessage( {name:"John"} ), mountNode);
No literals?
A simple React component (using the
JSX pre-processor)
var HelloMessage = React.createClass({!
render: function() {!
return <div>Hello {this.props.name}</div>;!
}!
});!
!
React.renderComponent(!
<HelloMessage name="John" />, mountNode);
React components are functions from
application state to a DOM tree
Now let’s take a leap and look at the same
component, written in Om
A simple Om component
(def app-state (atom {:name "Leo"}))!
!
(defn hello-message [app owner]!
(reify om/IRender!
(render [_]!
(dom/div nil!
(str "Hello " (:name app))))))!
!
!
(om/root hello-message app-state!
{:target (. js/document (getElementById "hello"))})!
Om/React’s component lifecycle
IWillMountIInitState IShouldUpdate
IRender
IRenderState
IShouldUpdate
‣ Called on app state changes but before rendering
‣ This is where React uses its fast diff algorithm
‣ Om components implement the fastest algorithm possible: a simple
reference equality check
‣ Generally, you won’t have to implement this
IInitState & IRenderState
‣ Initialise component local state using IInitState
‣ Use IRenderState to work with it and render the component
IInitState & IRenderState
(defn counter [app owner]!
(reify!
om/IInitState!
(init-state [_]!
{:clicks 0})!
om/IRenderState!
(render-state [_ state]!
(dom/div nil!
(str "Clicks " (:clicks state))!
(dom/button #js {:onClick!
#(om/set-state! owner :clicks (inc (:clicks state)))}!
"Click me!")))))!
!
(om/root counter (atom {})!
{:target (. js/document (getElementById "app"))})!
IRender
‣ Same as IRenderState…
‣ …except it doesn’t depend on the component local state to render
IRender
(def app-state (atom {:name "Leo"}))!
!
(defn hello-message [app owner]!
(reify om/IRender!
(render [_]!
(dom/div nil!
(str "Hello " (:name app))))))!
!
!
(om/root hello-message app-state!
{:target (. js/document (getElementById "hello"))})!
A larger example
A larger example
A reusable editable component
(defn editable [text owner]!
(reify!
om/IInitState!
(init-state [_]!
{:editing false})!
om/IRenderState!
(render-state [_ {:keys [editing]}]!
(dom/li nil!
(dom/span #js {:style (display (not editing))} (om/value text))!
(dom/input!
#js {:style (display editing)!
:value (om/value text)!
:onChange #(handle-change % text owner)!
:onKeyPress #(when (== (.-keyCode %) 13)!
(commit-change text owner))!
:onBlur (fn [e] (commit-change text owner))})!
(dom/button!
#js {:style (display (not editing))!
:onClick #(om/set-state! owner :editing true)}!
"Edit")))))!
From https://github.com/swannodette/om/wiki/Basic-Tutorial
A reusable editable component
(defn editable [text owner]!
(reify!
om/IInitState!
(init-state [_]!
{:editing false})!
om/IRenderState!
(render-state [_ {:keys [editing]}]!
(dom/li nil!
(dom/span #js {:style (display (not editing))} (om/value text))!
(dom/input!
#js {:style (display editing)!
:value (om/value text)!
:onChange #(handle-change % text owner)!
:onKeyPress #(when (== (.-keyCode %) 13)!
(commit-change text owner))!
:onBlur (fn [e] (commit-change text owner))})!
(dom/button!
#js {:style (display (not editing))!
:onClick #(om/set-state! owner :editing true)}!
"Edit")))))!
From https://github.com/swannodette/om/wiki/Basic-Tutorial
A reusable editable component
(defn editable [text owner]!
(reify!
om/IInitState!
(init-state [_]!
{:editing false})!
om/IRenderState!
(render-state [_ {:keys [editing]}]!
(dom/li nil!
(dom/span #js {:style (display (not editing))} (om/value text))!
(dom/input!
#js {:style (display editing)!
:value (om/value text)!
:onChange #(handle-change % text owner)!
:onKeyPress #(when (== (.-keyCode %) 13)!
(commit-change text owner))!
:onBlur (fn [e] (commit-change text owner))})!
(dom/button!
#js {:style (display (not editing))!
:onClick #(om/set-state! owner :editing true)}!
"Edit")))))!
From https://github.com/swannodette/om/wiki/Basic-Tutorial
The speakers view
(defn speakers-view [app owner]!
(reify!
om/IRender!
(render [_]!
(dom/div nil!
(dom/div #js {:id "speakers"!
:style #js {:float "left"}}!
(dom/h2 nil "Speakers")!
(dom/button #js {:onClick undo} "Undo")!
(dom/button #js {:onClick reset-app-state} "Reset")!
(apply dom/ul nil!
(om/build-all speaker-view (speakers app)!
{:shared {:app-state app}})))!
(om/build speaker-details-view app)))))
This is how you build
components
The Sessions view
Same deal as before
(defn sessions-view [app owner]!
(reify!
om/IRender!
(render [_]!
(dom/div #js {:id "sessions"}!
(dom/h2 nil "Sessions")!
(apply dom/ul nil!
(map #(om/build editable %) (vals (:sessions
app))))))))!
Apps can have multiple roots
(om/root speakers-view app-state!
{:target (. js/document (getElementById "speakers"))})!
!
(om/root sessions-view app-state!
{:target (. js/document (getElementById "sessions"))})!
You can have multiple “mini-apps” inside your main app
Makes it easy to try Om in a specific section/feature
What about “undo” and “reset”?
Implementing undo
(def app-state (atom speaker-data))!
(def app-history (atom [@app-state]))!
!
(add-watch app-state :history!
(fn [_ _ _ n]!
(when-not (= (last @app-history) n)!
(swap! app-history conj n))!
(let [c (count @app-history)]!
(prn c " Saved items in app history"))))!
!
(defn undo []!
(when (> (count @app-history) 1)!
(swap! app-history pop)!
(reset! app-state (last @app-history))))!
Implementing reset
(defn reset-app-state []!
(reset! app-state (first @app-history))!
(reset! app-history [@app-state]))!
Om/React components are functions from state to
DOM trees
With immutable data structures we can access
every version of the application state
So we simply update the application state, causing
the components to get re-rendered
A bit of live coding
Summary
‣ With Om, you’re not using a crippled template language, you can
leverage all of Clojurescript (including other DOM libraries)
‣ Rendering and display logic are inevitably coupled. Om/React
acknowledges that a bundles them in components
‣ The whole app is re-rendered on every state change, making it easier to
reason about
‣ This is efficient thanks to immutable data structures
Summary
‣ Clojurescript also provides a better development experience with a
powerful browser REPL much like what you’d get with Clojure on the JVM
‣ Source maps are here today
‣ Bottom line is that Clojurescript is a serious contender
References
‣ Code: https://github.com/leonardoborges/lambdajam-2014-om-talk
‣ React documentation: http://facebook.github.io/react/
‣ Om documentation: https://github.com/swannodette/om/wiki/
Documentation#build
‣ Basic Tutorial: https://github.com/swannodette/om/wiki/Basic-Tutorial
Thanks!
Questions?
Leonardo Borges
@leonardo_borges
www.leonardoborges.com
www.thoughtworks.com

More Related Content

What's hot

Intro to React
Intro to ReactIntro to React
Intro to ReactTroy Miles
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptŁukasz Kużyński
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projectsIgnacio Martín
 
React.js or why DOM finally makes sense
React.js or why DOM finally makes senseReact.js or why DOM finally makes sense
React.js or why DOM finally makes senseEldar Djafarov
 
Avoiding callback hell with promises
Avoiding callback hell with promisesAvoiding callback hell with promises
Avoiding callback hell with promisesTorontoNodeJS
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jscacois
 
History of jQuery
History of jQueryHistory of jQuery
History of jQueryjeresig
 
Mobile Day - React Native
Mobile Day - React NativeMobile Day - React Native
Mobile Day - React NativeSoftware Guru
 
JavaScript - From Birth To Closure
JavaScript - From Birth To ClosureJavaScript - From Birth To Closure
JavaScript - From Birth To ClosureRobert Nyman
 
$q and Promises in AngularJS
$q and Promises in AngularJS $q and Promises in AngularJS
$q and Promises in AngularJS a_sharif
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Codemotion
 
Difference between java script and jquery
Difference between java script and jqueryDifference between java script and jquery
Difference between java script and jqueryUmar Ali
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.jsMatthew Beale
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)Domenic Denicola
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IVisual Engineering
 
Maintainable JavaScript 2011
Maintainable JavaScript 2011Maintainable JavaScript 2011
Maintainable JavaScript 2011Nicholas Zakas
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveepamspb
 

What's hot (20)

Intro to React
Intro to ReactIntro to React
Intro to React
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
React.js or why DOM finally makes sense
React.js or why DOM finally makes senseReact.js or why DOM finally makes sense
React.js or why DOM finally makes sense
 
Avoiding callback hell with promises
Avoiding callback hell with promisesAvoiding callback hell with promises
Avoiding callback hell with promises
 
Discover React
Discover ReactDiscover React
Discover React
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
History of jQuery
History of jQueryHistory of jQuery
History of jQuery
 
React
React React
React
 
Mobile Day - React Native
Mobile Day - React NativeMobile Day - React Native
Mobile Day - React Native
 
JavaScript - From Birth To Closure
JavaScript - From Birth To ClosureJavaScript - From Birth To Closure
JavaScript - From Birth To Closure
 
$q and Promises in AngularJS
$q and Promises in AngularJS $q and Promises in AngularJS
$q and Promises in AngularJS
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
 
Difference between java script and jquery
Difference between java script and jqueryDifference between java script and jquery
Difference between java script and jquery
 
Containers & Dependency in Ember.js
Containers & Dependency in Ember.jsContainers & Dependency in Ember.js
Containers & Dependency in Ember.js
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte I
 
Maintainable JavaScript 2011
Maintainable JavaScript 2011Maintainable JavaScript 2011
Maintainable JavaScript 2011
 
RSpec
RSpecRSpec
RSpec
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 

Viewers also liked

WebSockets, Unity3D, and Clojure
WebSockets, Unity3D, and ClojureWebSockets, Unity3D, and Clojure
WebSockets, Unity3D, and ClojureJosh Glover
 
Unity and WebSockets
Unity and WebSocketsUnity and WebSockets
Unity and WebSocketsJosh Glover
 
The Case for React.js and ClojureScript
The Case for React.js and ClojureScriptThe Case for React.js and ClojureScript
The Case for React.js and ClojureScriptMurilo Pereira
 
ClojureScript interfaces to React
ClojureScript interfaces to ReactClojureScript interfaces to React
ClojureScript interfaces to ReactMichiel Borkent
 
The algebra of library design
The algebra of library designThe algebra of library design
The algebra of library designLeonardo Borges
 
Clojure の各種React系ラッパーライブラリのサーバーサイドレンダリングの現状について
Clojure の各種React系ラッパーライブラリのサーバーサイドレンダリングの現状についてClojure の各種React系ラッパーライブラリのサーバーサイドレンダリングの現状について
Clojure の各種React系ラッパーライブラリのサーバーサイドレンダリングの現状についてKazuhiro Hara
 

Viewers also liked (7)

WebSockets, Unity3D, and Clojure
WebSockets, Unity3D, and ClojureWebSockets, Unity3D, and Clojure
WebSockets, Unity3D, and Clojure
 
Unity and WebSockets
Unity and WebSocketsUnity and WebSockets
Unity and WebSockets
 
The Case for React.js and ClojureScript
The Case for React.js and ClojureScriptThe Case for React.js and ClojureScript
The Case for React.js and ClojureScript
 
ClojureScript interfaces to React
ClojureScript interfaces to ReactClojureScript interfaces to React
ClojureScript interfaces to React
 
The algebra of library design
The algebra of library designThe algebra of library design
The algebra of library design
 
Unity WebSocket
Unity WebSocketUnity WebSocket
Unity WebSocket
 
Clojure の各種React系ラッパーライブラリのサーバーサイドレンダリングの現状について
Clojure の各種React系ラッパーライブラリのサーバーサイドレンダリングの現状についてClojure の各種React系ラッパーライブラリのサーバーサイドレンダリングの現状について
Clojure の各種React系ラッパーライブラリのサーバーサイドレンダリングの現状について
 

Similar to High Performance web apps in Om, React and ClojureScript

Content-Driven Apps with React
Content-Driven Apps with ReactContent-Driven Apps with React
Content-Driven Apps with ReactNetcetera
 
Combining Angular and React Together
Combining Angular and React TogetherCombining Angular and React Together
Combining Angular and React TogetherSebastian Pederiva
 
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...Codemotion
 
Introduction to React for Frontend Developers
Introduction to React for Frontend DevelopersIntroduction to React for Frontend Developers
Introduction to React for Frontend DevelopersSergio Nakamura
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidNelson Glauber Leal
 
React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)Chiew Carol
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous MerbMatt Todd
 
React js programming concept
React js programming conceptReact js programming concept
React js programming conceptTariqul islam
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahNick Plante
 
Build UI of the Future with React 360
Build UI of the Future with React 360Build UI of the Future with React 360
Build UI of the Future with React 360RapidValue
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications Juliana Lucena
 
ReactJS - A quick introduction to Awesomeness
ReactJS - A quick introduction to AwesomenessReactJS - A quick introduction to Awesomeness
ReactJS - A quick introduction to AwesomenessRonny Haase
 
React js - The Core Concepts
React js - The Core ConceptsReact js - The Core Concepts
React js - The Core ConceptsDivyang Bhambhani
 

Similar to High Performance web apps in Om, React and ClojureScript (20)

Simple React Todo List
Simple React Todo ListSimple React Todo List
Simple React Todo List
 
Content-Driven Apps with React
Content-Driven Apps with ReactContent-Driven Apps with React
Content-Driven Apps with React
 
Combining Angular and React Together
Combining Angular and React TogetherCombining Angular and React Together
Combining Angular and React Together
 
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
ClojureScript - Making Front-End development Fun again - John Stevenson - Cod...
 
Introduction to React for Frontend Developers
Introduction to React for Frontend DevelopersIntroduction to React for Frontend Developers
Introduction to React for Frontend Developers
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no Android
 
React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)React Native +Redux + ES6 (Updated)
React Native +Redux + ES6 (Updated)
 
How to React Native
How to React NativeHow to React Native
How to React Native
 
Adventurous Merb
Adventurous MerbAdventurous Merb
Adventurous Merb
 
React js programming concept
React js programming conceptReact js programming concept
React js programming concept
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
Build UI of the Future with React 360
Build UI of the Future with React 360Build UI of the Future with React 360
Build UI of the Future with React 360
 
ReactJS
ReactJSReactJS
ReactJS
 
Os Haase
Os HaaseOs Haase
Os Haase
 
Elixir on Containers
Elixir on ContainersElixir on Containers
Elixir on Containers
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
 
ReactJS - A quick introduction to Awesomeness
ReactJS - A quick introduction to AwesomenessReactJS - A quick introduction to Awesomeness
ReactJS - A quick introduction to Awesomeness
 
React js - The Core Concepts
React js - The Core ConceptsReact js - The Core Concepts
React js - The Core Concepts
 
Lec7Handout.ppt
Lec7Handout.pptLec7Handout.ppt
Lec7Handout.ppt
 
The Road To Redux
The Road To ReduxThe Road To Redux
The Road To Redux
 

More from Leonardo Borges

Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015Leonardo Borges
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Leonardo Borges
 
From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019Leonardo Borges
 
Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Leonardo Borges
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
 
Programação functional reativa: lidando com código assíncrono
Programação functional reativa: lidando com código assíncronoProgramação functional reativa: lidando com código assíncrono
Programação functional reativa: lidando com código assíncronoLeonardo Borges
 
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Leonardo Borges
 
Intro to Clojure's core.async
Intro to Clojure's core.asyncIntro to Clojure's core.async
Intro to Clojure's core.asyncLeonardo Borges
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptLeonardo Borges
 
Clojure/West 2013 in 30 mins
Clojure/West 2013 in 30 minsClojure/West 2013 in 30 mins
Clojure/West 2013 in 30 minsLeonardo Borges
 
Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012Leonardo Borges
 
The many facets of code reuse in JavaScript
The many facets of code reuse in JavaScriptThe many facets of code reuse in JavaScript
The many facets of code reuse in JavaScriptLeonardo Borges
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Leonardo Borges
 
Heroku addons development - Nov 2011
Heroku addons development - Nov 2011Heroku addons development - Nov 2011
Heroku addons development - Nov 2011Leonardo Borges
 
Clouds against the Floods (RubyConfBR2011)
Clouds against the Floods (RubyConfBR2011) Clouds against the Floods (RubyConfBR2011)
Clouds against the Floods (RubyConfBR2011) Leonardo Borges
 
Clouds Against the Floods
Clouds Against the FloodsClouds Against the Floods
Clouds Against the FloodsLeonardo Borges
 

More from Leonardo Borges (20)

Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
Realtime collaboration with Clojure - EuroClojure - Barcelona, 2015
 
Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015Parametricity - #cljsyd - May, 2015
Parametricity - #cljsyd - May, 2015
 
From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019
 
Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015Futures e abstração - QCon São Paulo 2015
Futures e abstração - QCon São Paulo 2015
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
Programação functional reativa: lidando com código assíncrono
Programação functional reativa: lidando com código assíncronoProgramação functional reativa: lidando com código assíncrono
Programação functional reativa: lidando com código assíncrono
 
Monads in Clojure
Monads in ClojureMonads in Clojure
Monads in Clojure
 
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
Clojure Macros Workshop: LambdaJam 2013 / CUFP 2013
 
Intro to Clojure's core.async
Intro to Clojure's core.asyncIntro to Clojure's core.async
Intro to Clojure's core.async
 
Functional Reactive Programming in Clojurescript
Functional Reactive Programming in ClojurescriptFunctional Reactive Programming in Clojurescript
Functional Reactive Programming in Clojurescript
 
Clojure/West 2013 in 30 mins
Clojure/West 2013 in 30 minsClojure/West 2013 in 30 mins
Clojure/West 2013 in 30 mins
 
Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012Clojure Reducers / clj-syd Aug 2012
Clojure Reducers / clj-syd Aug 2012
 
The many facets of code reuse in JavaScript
The many facets of code reuse in JavaScriptThe many facets of code reuse in JavaScript
The many facets of code reuse in JavaScript
 
Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012Continuation Passing Style and Macros in Clojure - Jan 2012
Continuation Passing Style and Macros in Clojure - Jan 2012
 
Heroku addons development - Nov 2011
Heroku addons development - Nov 2011Heroku addons development - Nov 2011
Heroku addons development - Nov 2011
 
Clouds against the Floods (RubyConfBR2011)
Clouds against the Floods (RubyConfBR2011) Clouds against the Floods (RubyConfBR2011)
Clouds against the Floods (RubyConfBR2011)
 
Clouds Against the Floods
Clouds Against the FloodsClouds Against the Floods
Clouds Against the Floods
 
Arel in Rails 3
Arel in Rails 3Arel in Rails 3
Arel in Rails 3
 
Testing with Spring
Testing with SpringTesting with Spring
Testing with Spring
 
JRuby in The Enterprise
JRuby in The EnterpriseJRuby in The Enterprise
JRuby in The Enterprise
 

Recently uploaded

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 

Recently uploaded (20)

Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 

High Performance web apps in Om, React and ClojureScript

  • 1. High Performance Web UI's with Om and React LambdaJam - Brisbane, 2014 Leonardo Borges @leonardo_borges www.leonardoborges.com www.thoughtworks.com
  • 2. About ‣ ThoughtWorker ‣ Functional Programming & Clojure advocate ‣ Founder of the Sydney Clojure User Group ‣ Currently writing “Clojure Reactive Programming”
  • 4. And that makes us happy
  • 5. However if you do client-side web development, you’re out of luck
  • 8. Today we’ll see one of them: Clojurescript
  • 9. What we’ll see ‣ An Overview of React and how it enables fast rendering ‣ Meet Om, a ClojureScript interface to React ‣ Boosting React’s rendering performance with immutable data structures ‣ A simple demo featuring “data binding” and undo functionality
  • 10. React ‣ Created by Facebook for building user interfaces ‣ The V in MVC ‣ Self-contained components ‣ Doesn’t make assumptions about your stack - can be used with anything
  • 11. Self-contained components ‣ React combines display logic and DOM generation ‣ Components are themselves loosely coupled ‣ The whole app is re-rendered on every update ‣ Virtual DOM ‣ Efficient diff algorithm
  • 12. Efficient diff algorithm ‣ Creates a virtual version of the DOM ‣ As the application state changes new DOM trees are generated ‣ React diffs the trees and computes the minimal set of changes ‣ Finally it applies the changes to the real DOM
  • 13. A simple React component var HelloMessage = React.createClass({! displayName: 'HelloMessage',! render: function() {! return React.DOM.div(null, "Hello ", this.props.name);! }! });! ! React.renderComponent(! HelloMessage( {name:"John"} ), mountNode);
  • 15. A simple React component (using the JSX pre-processor) var HelloMessage = React.createClass({! render: function() {! return <div>Hello {this.props.name}</div>;! }! });! ! React.renderComponent(! <HelloMessage name="John" />, mountNode);
  • 16. React components are functions from application state to a DOM tree
  • 17. Now let’s take a leap and look at the same component, written in Om
  • 18. A simple Om component (def app-state (atom {:name "Leo"}))! ! (defn hello-message [app owner]! (reify om/IRender! (render [_]! (dom/div nil! (str "Hello " (:name app))))))! ! ! (om/root hello-message app-state! {:target (. js/document (getElementById "hello"))})!
  • 19. Om/React’s component lifecycle IWillMountIInitState IShouldUpdate IRender IRenderState
  • 20. IShouldUpdate ‣ Called on app state changes but before rendering ‣ This is where React uses its fast diff algorithm ‣ Om components implement the fastest algorithm possible: a simple reference equality check ‣ Generally, you won’t have to implement this
  • 21. IInitState & IRenderState ‣ Initialise component local state using IInitState ‣ Use IRenderState to work with it and render the component
  • 22. IInitState & IRenderState (defn counter [app owner]! (reify! om/IInitState! (init-state [_]! {:clicks 0})! om/IRenderState! (render-state [_ state]! (dom/div nil! (str "Clicks " (:clicks state))! (dom/button #js {:onClick! #(om/set-state! owner :clicks (inc (:clicks state)))}! "Click me!")))))! ! (om/root counter (atom {})! {:target (. js/document (getElementById "app"))})!
  • 23. IRender ‣ Same as IRenderState… ‣ …except it doesn’t depend on the component local state to render
  • 24. IRender (def app-state (atom {:name "Leo"}))! ! (defn hello-message [app owner]! (reify om/IRender! (render [_]! (dom/div nil! (str "Hello " (:name app))))))! ! ! (om/root hello-message app-state! {:target (. js/document (getElementById "hello"))})!
  • 27. A reusable editable component (defn editable [text owner]! (reify! om/IInitState! (init-state [_]! {:editing false})! om/IRenderState! (render-state [_ {:keys [editing]}]! (dom/li nil! (dom/span #js {:style (display (not editing))} (om/value text))! (dom/input! #js {:style (display editing)! :value (om/value text)! :onChange #(handle-change % text owner)! :onKeyPress #(when (== (.-keyCode %) 13)! (commit-change text owner))! :onBlur (fn [e] (commit-change text owner))})! (dom/button! #js {:style (display (not editing))! :onClick #(om/set-state! owner :editing true)}! "Edit")))))! From https://github.com/swannodette/om/wiki/Basic-Tutorial
  • 28. A reusable editable component (defn editable [text owner]! (reify! om/IInitState! (init-state [_]! {:editing false})! om/IRenderState! (render-state [_ {:keys [editing]}]! (dom/li nil! (dom/span #js {:style (display (not editing))} (om/value text))! (dom/input! #js {:style (display editing)! :value (om/value text)! :onChange #(handle-change % text owner)! :onKeyPress #(when (== (.-keyCode %) 13)! (commit-change text owner))! :onBlur (fn [e] (commit-change text owner))})! (dom/button! #js {:style (display (not editing))! :onClick #(om/set-state! owner :editing true)}! "Edit")))))! From https://github.com/swannodette/om/wiki/Basic-Tutorial
  • 29. A reusable editable component (defn editable [text owner]! (reify! om/IInitState! (init-state [_]! {:editing false})! om/IRenderState! (render-state [_ {:keys [editing]}]! (dom/li nil! (dom/span #js {:style (display (not editing))} (om/value text))! (dom/input! #js {:style (display editing)! :value (om/value text)! :onChange #(handle-change % text owner)! :onKeyPress #(when (== (.-keyCode %) 13)! (commit-change text owner))! :onBlur (fn [e] (commit-change text owner))})! (dom/button! #js {:style (display (not editing))! :onClick #(om/set-state! owner :editing true)}! "Edit")))))! From https://github.com/swannodette/om/wiki/Basic-Tutorial
  • 30. The speakers view (defn speakers-view [app owner]! (reify! om/IRender! (render [_]! (dom/div nil! (dom/div #js {:id "speakers"! :style #js {:float "left"}}! (dom/h2 nil "Speakers")! (dom/button #js {:onClick undo} "Undo")! (dom/button #js {:onClick reset-app-state} "Reset")! (apply dom/ul nil! (om/build-all speaker-view (speakers app)! {:shared {:app-state app}})))! (om/build speaker-details-view app))))) This is how you build components
  • 31. The Sessions view Same deal as before (defn sessions-view [app owner]! (reify! om/IRender! (render [_]! (dom/div #js {:id "sessions"}! (dom/h2 nil "Sessions")! (apply dom/ul nil! (map #(om/build editable %) (vals (:sessions app))))))))!
  • 32. Apps can have multiple roots (om/root speakers-view app-state! {:target (. js/document (getElementById "speakers"))})! ! (om/root sessions-view app-state! {:target (. js/document (getElementById "sessions"))})! You can have multiple “mini-apps” inside your main app Makes it easy to try Om in a specific section/feature
  • 33. What about “undo” and “reset”?
  • 34. Implementing undo (def app-state (atom speaker-data))! (def app-history (atom [@app-state]))! ! (add-watch app-state :history! (fn [_ _ _ n]! (when-not (= (last @app-history) n)! (swap! app-history conj n))! (let [c (count @app-history)]! (prn c " Saved items in app history"))))! ! (defn undo []! (when (> (count @app-history) 1)! (swap! app-history pop)! (reset! app-state (last @app-history))))!
  • 35. Implementing reset (defn reset-app-state []! (reset! app-state (first @app-history))! (reset! app-history [@app-state]))!
  • 36. Om/React components are functions from state to DOM trees
  • 37. With immutable data structures we can access every version of the application state
  • 38. So we simply update the application state, causing the components to get re-rendered
  • 39. A bit of live coding
  • 40. Summary ‣ With Om, you’re not using a crippled template language, you can leverage all of Clojurescript (including other DOM libraries) ‣ Rendering and display logic are inevitably coupled. Om/React acknowledges that a bundles them in components ‣ The whole app is re-rendered on every state change, making it easier to reason about ‣ This is efficient thanks to immutable data structures
  • 41. Summary ‣ Clojurescript also provides a better development experience with a powerful browser REPL much like what you’d get with Clojure on the JVM ‣ Source maps are here today ‣ Bottom line is that Clojurescript is a serious contender
  • 42. References ‣ Code: https://github.com/leonardoborges/lambdajam-2014-om-talk ‣ React documentation: http://facebook.github.io/react/ ‣ Om documentation: https://github.com/swannodette/om/wiki/ Documentation#build ‣ Basic Tutorial: https://github.com/swannodette/om/wiki/Basic-Tutorial