Upgrade to Pro — share decks privately, control downloads, hide ads and more …

BackboneConf 2014

BackboneConf 2014

Keynote at BackboneConf talking about ampersand.js, amp, and intelligent DOM diffing with virtual DOM.

229ec15028bae7f1d4cdcfe91e2380b0?s=128

Henrik Joreteg

December 16, 2014
Tweet

Transcript

  1. BackboneConf 2014 @HenrikJoreteg

  2. None
  3. SINGLE PAGE APPS

  4. SINGLE PAGE APPS

  5. NATIVE WEB APPS

  6. THE BROWSER ISN’T YOUR RENDERER

  7. THE BROWSER IS YOUR RUNTIME

  8. THE WEBVIEW IS YOUR RUNTIME

  9. MORE LOGIC MOVING TO FRONT-END JS

  10. DEVS WITH DIFFERENT BACKGROUNDS COMING TO JS

  11. BRINGING THEIR PATTERNS AND PREFERENCES

  12. ANGULAR EMBER AMPERSAND REACT POLYMER FLIGHT VUE CJS + OM

  13. BACKBONE IS VERY BROADLY DEPLOYED

  14. None
  15. WHY HAS BACKBONE BEEN SO POPULAR?

  16. "Backbone is an attempt to discover the minimal set of

    […] primitives that are generally useful when building web applications with JavaScript."
  17. "In an ecosystem where overarching, decides- everything-for-you frameworks are commonplace

    […] — Backbone should continue to be a tool that gives you the freedom to design the full experience of your web application."
  18. MINIMALISM + FLEXIBILITY

  19. THE OTHER SIDE OF MINIMALISM

  20. THERE’S A LOT THAT IT DOESN’T DO

  21. AND THERE ARE OTHER REPEATING PATTERNS

  22. HOW DO WE FILL THOSE GAPS?

  23. 1. ADD-ONS

  24. PAYPAL WALMART AIRBNB

  25. BUILT OWN FRAMEWORK ON TOP OF BACKBONE

  26. 2. DIFFERENT + LARGER CORE

  27. EMBER ANGULAR POLYMER REACT+FLUX

  28. "overarching, decides-everything-for-you frameworks"

  29. HIGHER ABSTRACTIONS

  30. "I’m more interested in optimizing a person’s understanding of problems

    than their understanding of solutions." - Kris Gale (former VPE Yammer)
  31. https://www.youtube.com/watch?v=Bp3Jy177NvU MARCO ROGERS @polotek FINDING PATTERNS ACROSS FRONT-END FRAMEWORKS:

  32. andyet.com

  33. ~30 DEVELOPERS GOBS OF JS APPS REALTIME APPS

  34. I WANT OUR TEAM TO BE AWESOME JS DEVELOPERS

  35. 3. NO CORE

  36. I STARTED USING BACKBONE AT 0.3

  37. FOR YEARS WE HAD BEEN BUILDING OUT A SET OF

    ADD-ONS
  38. I CAME FROM A DJANGO BACKGROUND

  39. WE BUILT OUR OWN MODELS TO USE WITH BACKBONE

  40. node.js

  41. npm + CommonJS Modules

  42. read.humanjavascript.com

  43. AS CRAZY AS IT MAY SOUND…

  44. I THINK EVEN BACKBONE IS TOO MONOLITHIC

  45. NOT IN FILESIZE BUT IN COUPLING

  46. LET ME EXPLAIN…

  47. MODELS ARE USEFUL FOR LOTS OF THINGS!

  48. CONNECTION STATE FOR SDK WITH A REALTIME CONNECTION

  49. MODELING TOUCH EVENTS IN A TOUCH LIBRARY

  50. 1. VIEW/ROUTER/COLLECTION 2. JQUERY 3. UNDERSCORE MY LIBRARY NOW REQUIRES:

  51. A SPECIFIC VERSION OF EACH OF THOSE

  52. AMPERSAND.JS

  53. THE NAME "ampersand.js" IS A FILTHY LIE

  54. BECAUSE NO SUCH FILE EXISTS! <script src="ampersand.js"></script>

  55. WE JUST NAMED IT SOMETHING SO IT’S EASIER TO TALK

    ABOUT
  56. THERE’S NOTHING YOU CAN DROP INTO A SCRIPT TAG WITHOUT

    A BUILD STEP
  57. SEPARATE COMMON.JS MODULES

  58. INDIVIDUALLY INSTALLED VIA NPM

  59. BUILD WITH BROWSERIFY OR WEBPACK

  60. ampersand-state ampersand-model ampersand-collection ampersand-rest-collection ampersand-view ampersand-router

  61. ampersand (the CLI) ampersand-app ampersand-view-switcher ampersand-input-view ampersand-select-view ampersand-form-view etc.

  62. INDIVIDUAL GITHUB REPOS

  63. STRICT SEMVER

  64. todomvc.com

  65. FLEXIBILITY MODULARITY SO WHAT?!

  66. ONLY SEND CODE YOU USE

  67. AMPERSAND TODOMVC: ~28kb min+gzip

  68. MODULARITY LETS YOU REMODEL THE KITCHEN WITHOUT BURNING DOWN THE

    WHOLE BUILDING
  69. Angular 2.0

  70. AMPERSAND + REACT

  71. BUT MODULARITY ISN’T THE ONLY FEATURE

  72. ONE EXAMPLE OF WHY WE FORKED

  73. SMARTER/STRICTER MODELS

  74. var model = new Backbone.Model({ name: 'henrik' }); model.on('change:name', function

    () { console.log('new changed'); }); model.set({name: 'bob'}); Backbone Models
  75. IF MODELS ARE OUR SOURCE OF TRUTH… WE WANT THEM

    TO BE MORE READABLE
  76. YOU HAVE TO DEFINE WHAT YOU STORE

  77. var Person = AmpersandState.extend({ props: { name:'string' } }); var

    model = new Model({name: 'henrik'}); model.on('change:name', someFunc); model.name = 'bob'; // still fires event model.name = 47; // throws TypeError
  78. SESSION STATE: RELATED, NOT PERSISTED

  79. var Person = AmpState.extend({ props: { name:'string' }, session: {

    active:'boolean' } }); var model = new Person({ name: 'henrik', active: true }); model.active; //=> true model.toJSON(); //=> {name: 'henrik'}
  80. GETTER/SETTER TRANFORMATIONS

  81. var Person = AmpState.extend({ props: { today: 'date' } });

    // unix timestamp coming in var henrik = new Person({today: '1418338921707'}); // getter returns Date Object henrik.today; //=> JS `Date` instance // timestamp when serializing JSON.stringify(henrik); //=> {today: 1418338921707}
  82. CACHED, OBSERVABLE DERIVED PROPERTIES

  83. var Person = AmpState.extend({ props: { name: 'string' }, derived:

    { nickName: { deps: ['name'], fn: function () { return this.name.slice(0, 3); } } } });
  84. var someone = new Person({name: 'henrik'}); someone.on('change:nickName', logChange); // computed

    only once and cached someone.nickName; //=> 'hen' // not triggered if result is same someone.name = 'henry'; // only if different someone.name = 'crazy'; // logs changed nick: 'cra'
  85. 1. derive from child models 2. derive from other derived

    3. useful for relationships between models 4. cannot set directly 5. resulting model code is more readable CACHED, EVENTED, DERIVED PROPERTIES
  86. READ MORE IN DOCS http://ampersandjs.com

  87. WEB + IRC CHATROOM: https://gitter.im/AmpersandJS/AmpersandJS https://irc.gitter.im/

  88. MODULES ALL THE WAY DOWN™

  89. WHAT ABOUT UNDERSCORE?

  90. None
  91. HOW MANY OF THOSE USE ONE OR TWO METHODS?

  92. INCONSEQUENTIAL WHEN SERVER-SIDE

  93. …OR WHEN BUILDING A CLIENTSIDE APP WITH IT

  94. BUT FEELS UNNECESSARY WHEN WRITING CLIENTSIDE LIBRARIES

  95. IF I’M WANTING A SINGLE FUNCTION THEN WHAT?

  96. None
  97. CROSS-BROWSER? NO UPSTREAM BUG FIXES

  98. WHAT ABOUT JQUERY?

  99. IDEALLY I WANT STUFF LIKE THIS TOO: addClass(element, 'someclass');

  100. INDIVIDUALLY INSTALLABLE CROSS-BROWSER TESTED API NEVER UPDATED STRICT SEMVER

  101. addClass(el, 'class1') addClass(el, 'class1', 'class2') addClass(el, [array of classes]) SUPPORTED

    APIS:
  102. 1.X.X API FOREVER

  103. LODASH?

  104. VERSIONED TOGETHER

  105. PREPARE THE TOMATOES AGAIN…

  106. None
  107. MAINTAINING PILES OF TINY MODULES IS A GIANT PAIN

  108. "Another flaw in the human character is that everybody wants

    to build and nobody wants to do maintenance." - Kurt Vonnegut
  109. 1. SINGLE GITHUB REPO 2. CONTAINING 40+ MODULES 3. WRITE

    DOC 4. WRITE IMPLEMENTATION 5. WRITE TEST 6. RUN BUILD
  110. CROSS-BROWSER TESTED WITH CI SYSTEM IE6+ using Travis CI +

    SauceLabs
  111. SHARED DOCUMENTATION SITE SIMPLE NAMES YOU CAN MEMORIZE TESTED/MANGED TOGETHER

  112. npm i --save amp-x

  113. http://amp.ampersandjs.com ~40 AVAILABLE NOW WILL KEEP GROWING

  114. THE VIEW LAYER IS THE HARDEST

  115. Philip Roberts JS Slinger Extraordinaire @philip_roberts

  116. SHARE SOME R+D

  117. TEMPLATING ON THE SERVER IS EASY TO GROK

  118. BUT NOW WE’RE MUTATING STATE

  119. DOM IS STATEFUL WE HAVE TO SYNC OUR STATE WITH

    ACTUAL DOM STATE
  120. None
  121. JEREMY CALLED IT…

  122. "In a finished Backbone app, you don't have to write

    the glue code that looks into the DOM to find an element with a specific id, and update the HTML manually — when the model changes, the views simply update themselves." - Backbone Docs
  123. <div><input/></div> CURRENT DOM: <div><input/><p>hi!</p></div> TARGET DOM:

  124. THE SIMPLE WAY: // assume we have 'el' element //

    with this HTML: // "<div><input/></div>" // we can just replace its contents // with a new string: el.innerHTML = "<input/><p>hi!</p>"
  125. IF INFREQUENT AND SIMPLE IT WORKS FINE

  126. NOT IDEAL FOR LARGER SECTIONS OF DOM OR IF USER

    INPUTS NEEDS TO MAINTAIN FOCUS
  127. WHAT IF WE COULD DO THIS? mutateElement(el, "<div><input/><p>hi!</p></div>");

  128. .mutateElement() WOULD DO THIS: var pTag = document.createElement('p'); pTag.textContent =

    "hi!" el.appendChild(pTag);
  129. THEN WE ONLY UPDATE WHAT’S ACTUALLY DIFFERENT

  130. NO THRASHING DOM WITHOUT REASON

  131. IF DOM ALREADY MATCHES IT DOES NOTHING

  132. DOM DIFFING™

  133. DOM DIFFING™

  134. IF WE COULD DO THIS WITH HIGH PERFORMANCE BINDINGS BECOME

    SIMPLER
  135. REACT http://facebook.github.io/react/

  136. REACT + BACKBONE IN SUMMARY: var MyView = React.createClass({ getInitialState:

    function () { this.props.model = new Model(); this.props.model.on('change', this.forceUpdate, this); }, render: function () {
 return ( <div> <p>{this.model.name}</p> </div> ) } });
  137. DOWNSIDES: THEIR TEMPLATING THEIR VIRTUAL DOM THEIR APP PATTERNS

  138. CAN WE JUST STEAL THEIR BEST IDEAS?

  139. WHAT IF WE COULD DO IT WITH HTML STRINGS?

  140. THEN WE COULD GENERATE HTML USING ANY TEMPLATE LIBRARY!

  141. 1. PARSE HTML INTO SOME SORT 
 OF "AST" OR

    VIRTUAL DOM
  142. 2. DIFF THAT "AST" AGAINST THE LAST ONE

  143. 3. GENERATE A SET OF DOM TRANSFORMS FROM THAT DIFF

  144. 4. APPLY THEM TO THE DOM

  145. THESE ARE ALL "SOLVED PROBLEMS"

  146. BIG QUESTION IS PERFORMANCE

  147. EVERYONE KNOWS YOU SHOULDN’T WRITE AN HTML PARSER

  148. …ESPECIALLY WITH REGEX

  149. None
  150. YES… BUT…

  151. BUT WE’RE NOT PARSING ARBITRARY HTML, WE’RE PARSING HTML WE

    CONTROL
  152. A FEW SIMPLIFYING ASSUMPTIONS AND WE CAN DO IT, QUITE

    WELL
  153. {{ DEMO }}

  154. VIRTUAL DOM https://github.com/Matt-Esch/virtual-dom

  155. 1. SIMPLER VIEWS 2. LESS BINDINGS 3. EASIER TO GROK

    WHAT’S THE ACUTAL VALUE?
  156. INITIAL FINDINGS: 1. ~SAME PERFORMANCE AS REPLACE 2. FILESIZE: 7.25kb

    min + gzip 3. NESTED VIEW COMPONENTS WORK 4. CHOICE OF TEMPLATING LANGUAGE
  157. A VIEW MIXIN WORKS WITH BACKBONE + AMPERSAND

  158. github.com/AmpersandJS/ampersand-virtual-dom-mixin Mixin: github.com/HenrikJoreteg/html-parse-stringify HTML parse:

  159. CURRENT FLOW: 1. any template language 2. HTML string 3.

    parse into AST 4. generate vdom 5. get diffs 6. apply DOM transforms
  160. CURRENT FLOW: 1. any template language 2. HTML string 3.

    parse into AST 4. generate vdom 5. get diffs 6. apply DOM transforms
  161. CURRENT FLOW: 1. any template language 2. HTML string 3.

    parse into AST 4. generate vdom 5. get diffs 6. apply DOM transforms
  162. POTENTIAL OTHER THINGS? Simpler serverside rendering Do parsing in a

    web-worker?
  163. LET’S WORK TOWARD A MORE FLEXIBLE AND DECOUPLED FUTURE

  164. amp.ampersandjs.com AMP ampersandjs.com AMPERSAND github.com/AmpersandJS/ampersand-virtual-dom-mixin BB/Ampersand View Mixin

  165. THANKS! @HenrikJoreteg, andyet.com