The Case for React.js and ClojureScript


Published on

Sonian Tech Talk presentation given on may 2, 2014.

Published in: Software, Technology

The Case for React.js and ClojureScript

  1. 1. The Case for React.js and ClojureScript Murilo Pereira @mpereira May2, 2014
  2. 2. Problem
  3. 3. Building UIs is difficult.
  4. 4. Modern Web UIs visualrepresentationsofdatachangingovertime respondtoasynchronoususerevents transitionboththeunderlyingdataanditselftonew states
  5. 5. "Data changing over time is the root of all evil."
  6. 6. Incidental Complexity JavaScriptisn't DOM is stateful reactive
  7. 7. What if the JavaScript DOM API was reactive?
  8. 8. functiontweetScore(tweet){ return(tweet.favorites_count+tweet.retweets_count); } functioncompareTweetsByScore(a,b){ return(tweetScore(b)-tweetScore(a)); } functionrenderApplication(tweets){ return(document.dom.ul( {class:'tweets'}, tweets .sort(compareTweetsByScore) .slice(0,5) .map(function(tweet){ return({class:'tweet'},tweet.text); }) )); } vartweets=fetchTweets({username:'mpereira'},{limit:20}); document.dom.render(renderApplication(tweets),document.body);
  9. 9. Possible solution: Data binding
  10. 10. Data Binding Observables Computed properties Backbone, Ember, Meteor, etal.
  11. 11. Contemporary data binding is not simple.
  12. 12. Simple Notto be mistaken for "easy" Easiness = Familiarity(subjective) Simplicity= "Does/is one thing"(objective)
  13. 13. Data Binding Application logic entangled with observables Forces us to compose our programs with framework constructs instead of language constructs (functions and data structures)
  14. 14. "How often are you fighting the framework?"
  15. 15. Dirty-checking (Angular) Also susceptible to the problems of databinding.
  16. 16.
  17. 17. Complex
  18. 18. Even with shortcomings it's still possible to build complex, modern UIs using contemporary MVC frameworks.
  19. 19. "We can create precisely the same programs we're creating right now with drastically simpler tools." Rich Hickey
  20. 20. A different solution to the same problem.
  21. 21. React.js
  22. 22. React.js Libraryfor creatingUIs Renders the DOM and responds to user events Can be thoughtof as the Vin MVC
  23. 23. Remember our utopic example a few slides back?
  24. 24. functiontweetScore(tweet){ return(tweet.favorites_count+tweet.retweets_count); } functioncompareTweetsByScore(a,b){ return(tweetScore(b)-tweetScore(a)); } functionrenderApplication(tweets){ return(document.dom.ul( {class:'tweets'}, tweets .sort(compareTweetsByScore) .slice(0,5) .map(function(tweet){ return({class:'tweet'},tweet.text); }) )); } vartweets=fetchTweets({username:'mpereira'},{limit:20}); document.dom.render(renderApplication(tweets),document.body);
  25. 25. It's actually valid React.js code
  26. 26. functiontweetScore(tweet){ return(tweet.favorites_count+tweet.retweets_count); } functioncompareTweetsByScore(a,b){ return(tweetScore(b)-tweetScore(a)); } functionrenderApplication(tweets){ return(React.DOM.ul( {className:'tweets'}, tweets .sort(compareTweetsByScore) .slice(0,5) .map(function(tweet){ return({className:'tweet'},tweet.text); }) )); } vartweets=fetchTweets({username:'mpereira'},{limit:20}); React.renderComponent(renderApplication(tweets),document.body);
  27. 27. React gives us a minimally leaky abstraction for a reactive JavaScript/DOM environment.
  28. 28. Data Component DOM
  29. 29. Model View DOM
  30. 30. M3 V2 DOM M2 M4 M5M1 V1 V3
  31. 31. Data C3 DOM C4C2 C5C1
  32. 32. Components
  33. 33. Components Idempotent functions that describe your UI at any point in time.
  34. 34. component(data) = VDOM
  35. 35. component(data_1) = VDOM_1 *user inputchanges datafrom data_1 to data_2* component(data_2) = VDOM_2 diffVDOMs(VDOM_1, VDOM_2) = diff DOMOperations(diff) = operations applyDOMOperations(operations, document.body)
  36. 36. Best part? You don't even have to worry about this. Just build components.
  37. 37. Every place data is displayed is guaranteed to be up-to-date.  No need for KVO or marking HTML templates with framework directives.
  38. 38. Frees the programmer from doing manual, explicit DOM operations.
  39. 39. But what about the performance? Isn't diffing VDOMs slow? Why have VDOMs if the browser already has a DOM?
  40. 40. The DOM is slow.
  41. 41. The DOM is slow Queryingmayrequire tree traversal Mutations trigger viewportreflows, relayouts, repaints (CSS engine, etc.) Can also invalidate caches, requiringthe entire DOM to be reconstructed on the viewport
  42. 42. Having in-memory representations of the DOM allows React to have extremely fast UIs.
  43. 43. Virtual DOM (VDOM) Allows for components to have adeclarative API Performs the minimum amountof actualDOM operations through computingdiffs Handles DOM operations for you
  44. 44. "Performance isn't the [main] goal of the VDOM, but if you're worried with performance, most workloads are as fast or faster [than the MVC alternatives] out of the box." Pete Hunt
  45. 45. Components
  46. 46. Components allow you to express your program in the language of your problem domain. Rather than on the language of a particular framework.
  47. 47. Bill O'Reilly Tide comesin,tide goesout. You can'texplain that! Top Tweets Justhad #breakfast. @troll yes,definitelyplan on that. #selfie #instagram Good# morning.
  48. 48. Bill O'Reilly Top Tweets Tide comesin,tide goesout. You can'texplain that!#tides Justhad #breakfast. @troll yes,definitelyplan on that. #selfie #instagram Good# morning. Header Profile Tweets Top Tweets
  49. 49. varProfile=React.createClass({ render:function(){ return(React.DOM.div(null,[ React.DOM.img(null,this.props.user.image), React.DOM.p(null, ]); } }); varTweets=React.createClass({ render:function(){ return(React.DOM.ul(null,{ return(,tweet.text)); }); } }); varTopTweets=React.createClass({ render:function(){ return(React.DOM.div(null,[ React.DOM.h1(null,'TopTweets'), Profile({user:this.props.user}), Tweets({tweets:this.props.user.tweets}) ]); } }); React.renderComponent(TopTweets({user:user}),document.body);
  50. 50. varProfile=React.createClass({ render:function(){ return( <div> <imghref={this.props.user.image}/> <p>{}</p> </div> ); } }); varTweets=React.createClass({ render:function(){ return( <ul> {{ return(<li>tweet.text</li>); })}; </ul> ); } }); varTopTweets=React.createClass({ render:function(){ return( <div> <h1>TopTweets</h1> <Profileuser={this.props.user}/> <Tweetstweets={this.props.user.tweets}/> </div> ); }
  51. 51. TopTweets(data) = Header() + Profile(data_1) + Tweets(data_2)
  52. 52. Components are reusable and composable declarative representations of your UI.
  53. 53. Collateral Benefits
  54. 54. Collateral Benefits Render the application on the server (node.js, Java8's Nashhorn, etc.) UI testabilityfor free No templates!
  55. 55. React.js takeaways Declarative, fastUIs Express your programs in the language of your problem domain
  56. 56. ClojureScript
  57. 57. Problem JavaScript sucks We needJavaScript
  58. 58. JavaScript sucks No integers No module system Verbose syntax Confusing, inconsistentequalityoperators Confusing, inconsistentautomatic operator conversions Lack of block scope Non-uniform iterators Globalvariables bydefault NaN this No macros (yet...) etc.
  59. 59. We Need JavaScript Runtime is everywhere Runtime is improving(Web Sockets, geo-location, FS API, RAF, push notifications, WebRTC, WebGL, SVG, Canvas, Web Workers, IndexedDB, etc.)
  60. 60. Build better languages on top of JavaScript.
  61. 61. Compilers! Lots of them alreadyexist Onlyafew bringsignificantimprovements Popular ones CoffeeScript: mostlysyntax sugar TypeScript: typed supersetof JavaScript. Brings type checking, compile time errors
  62. 62. ClojureScript
  63. 63. ClojureScript is a Clojure compiler that targets JavaScript.
  64. 64. Why ClojureScript? Why Clojure? Why LISP?
  65. 65. Clojure is just a better language.
  66. 66. Numberofdays spentdesigning the language v1 JavaScript Clojure
  67. 67. ClojureScript LISP STM Runtime polymorphism The REPL Functionalprogramming Immutable datastructures Uniform API over immutable datastructures Macros Lazysequences Destructuring State VS Identity etc.
  68. 68. core.async (go(try (let[tweets (<?(get-tweets-for"swannodette")) first-url(<?(expand-url(first(parse-urlstweets)))) response (<?(http-getfirst-url))] (.js/console(log"Mostrecentlinktext:"response))) (catchjs/Errore (.js/console(error"Errorwiththetwitterverse:"e))))) Asynchronous Error Handling
  69. 69. The possibility of having access to the power of Clojure in the browser is immensely valuable.
  70. 70. Value To programmers, who willbe able to build better programs, with less bugs, faster. To the people and companies who willbenefitfrom those programs.
  71. 71. The developer experience has improved significantly.
  72. 72. Developer Experience Source maps Easilyreproducible tutorials Browser-connected in-editor REPLs Fastcompilation cycles Compatible libraries
  73. 73. Recommend you to check it out (butyou probablyhave, already)
  74. 74. Om
  75. 75. ClojureScript interface to React.
  76. 76. "Because of immutable data Om can deliver even better performance than React out of the box." David Nolen
  77. 77. 30-40X faster than JS MVCs nothing to do with ClojureScript. Ditch stateful objects, ditch events. Be declarative. Immutability. That's it. 5:39 AM - 15 Dec 2013 David Nolen @swannodette Follow 41 RETWEETS 39 FAVORITES
  78. 78. ???
  79. 79. ClojureScript Compiled, slower than hand-written JavaScript Uses immutable datastructures, slower than JavaScriptdata structures And yet Om's performance beats that of most JavaScript MVC frameworks
  80. 80. "Ideas have fundamental performance properties." Pete Hunt
  81. 81. Immutable data structures make React's diffing algorithm really smart.
  82. 82.  And more...
  83. 83. Takeaways
  84. 84. "Ideas have fundamental performance properties."
  85. 85. "Don't trade simplicity for familiarity."
  86. 86. And  .give it five minutes
  87. 87. Thanks!@mpereira
  88. 88. Learn React.js Why? Be Predictable, NotCorrect React: RethinkingBestPractices WhyReact? How GettingStarted Introduction to React.js Tutorial
  89. 89. Learn ClojureScript Why? ClojureScriptRationale The Future of JavaScriptMVC Frameworks Clojure Rationale WhyClojure? Beatingthe Averages How ClojureScript101 Translations from JavaScript LightTable ClojureScriptTutorial Om Tutorial