Slide 1

Slide 1 text

BackboneConf 2014 @HenrikJoreteg

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

SINGLE PAGE APPS

Slide 4

Slide 4 text

SINGLE PAGE APPS

Slide 5

Slide 5 text

NATIVE WEB APPS

Slide 6

Slide 6 text

THE BROWSER ISN’T YOUR RENDERER

Slide 7

Slide 7 text

THE BROWSER IS YOUR RUNTIME

Slide 8

Slide 8 text

THE WEBVIEW IS YOUR RUNTIME

Slide 9

Slide 9 text

MORE LOGIC MOVING TO FRONT-END JS

Slide 10

Slide 10 text

DEVS WITH DIFFERENT BACKGROUNDS COMING TO JS

Slide 11

Slide 11 text

BRINGING THEIR PATTERNS AND PREFERENCES

Slide 12

Slide 12 text

ANGULAR EMBER AMPERSAND REACT POLYMER FLIGHT VUE CJS + OM

Slide 13

Slide 13 text

BACKBONE IS VERY BROADLY DEPLOYED

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

WHY HAS BACKBONE BEEN SO POPULAR?

Slide 16

Slide 16 text

"Backbone is an attempt to discover the minimal set of […] primitives that are generally useful when building web applications with JavaScript."

Slide 17

Slide 17 text

"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."

Slide 18

Slide 18 text

MINIMALISM + FLEXIBILITY

Slide 19

Slide 19 text

THE OTHER SIDE OF MINIMALISM

Slide 20

Slide 20 text

THERE’S A LOT THAT IT DOESN’T DO

Slide 21

Slide 21 text

AND THERE ARE OTHER REPEATING PATTERNS

Slide 22

Slide 22 text

HOW DO WE FILL THOSE GAPS?

Slide 23

Slide 23 text

1. ADD-ONS

Slide 24

Slide 24 text

PAYPAL WALMART AIRBNB

Slide 25

Slide 25 text

BUILT OWN FRAMEWORK ON TOP OF BACKBONE

Slide 26

Slide 26 text

2. DIFFERENT + LARGER CORE

Slide 27

Slide 27 text

EMBER ANGULAR POLYMER REACT+FLUX

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

HIGHER ABSTRACTIONS

Slide 30

Slide 30 text

"I’m more interested in optimizing a person’s understanding of problems than their understanding of solutions." - Kris Gale (former VPE Yammer)

Slide 31

Slide 31 text

https://www.youtube.com/watch?v=Bp3Jy177NvU MARCO ROGERS @polotek FINDING PATTERNS ACROSS FRONT-END FRAMEWORKS:

Slide 32

Slide 32 text

andyet.com

Slide 33

Slide 33 text

~30 DEVELOPERS GOBS OF JS APPS REALTIME APPS

Slide 34

Slide 34 text

I WANT OUR TEAM TO BE AWESOME JS DEVELOPERS

Slide 35

Slide 35 text

3. NO CORE

Slide 36

Slide 36 text

I STARTED USING BACKBONE AT 0.3

Slide 37

Slide 37 text

FOR YEARS WE HAD BEEN BUILDING OUT A SET OF ADD-ONS

Slide 38

Slide 38 text

I CAME FROM A DJANGO BACKGROUND

Slide 39

Slide 39 text

WE BUILT OUR OWN MODELS TO USE WITH BACKBONE

Slide 40

Slide 40 text

node.js

Slide 41

Slide 41 text

npm + CommonJS Modules

Slide 42

Slide 42 text

read.humanjavascript.com

Slide 43

Slide 43 text

AS CRAZY AS IT MAY SOUND…

Slide 44

Slide 44 text

I THINK EVEN BACKBONE IS TOO MONOLITHIC

Slide 45

Slide 45 text

NOT IN FILESIZE BUT IN COUPLING

Slide 46

Slide 46 text

LET ME EXPLAIN…

Slide 47

Slide 47 text

MODELS ARE USEFUL FOR LOTS OF THINGS!

Slide 48

Slide 48 text

CONNECTION STATE FOR SDK WITH A REALTIME CONNECTION

Slide 49

Slide 49 text

MODELING TOUCH EVENTS IN A TOUCH LIBRARY

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

A SPECIFIC VERSION OF EACH OF THOSE

Slide 52

Slide 52 text

AMPERSAND.JS

Slide 53

Slide 53 text

THE NAME "ampersand.js" IS A FILTHY LIE

Slide 54

Slide 54 text

BECAUSE NO SUCH FILE EXISTS!

Slide 55

Slide 55 text

WE JUST NAMED IT SOMETHING SO IT’S EASIER TO TALK ABOUT

Slide 56

Slide 56 text

THERE’S NOTHING YOU CAN DROP INTO A SCRIPT TAG WITHOUT A BUILD STEP

Slide 57

Slide 57 text

SEPARATE COMMON.JS MODULES

Slide 58

Slide 58 text

INDIVIDUALLY INSTALLED VIA NPM

Slide 59

Slide 59 text

BUILD WITH BROWSERIFY OR WEBPACK

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

INDIVIDUAL GITHUB REPOS

Slide 63

Slide 63 text

STRICT SEMVER

Slide 64

Slide 64 text

todomvc.com

Slide 65

Slide 65 text

FLEXIBILITY MODULARITY SO WHAT?!

Slide 66

Slide 66 text

ONLY SEND CODE YOU USE

Slide 67

Slide 67 text

AMPERSAND TODOMVC: ~28kb min+gzip

Slide 68

Slide 68 text

MODULARITY LETS YOU REMODEL THE KITCHEN WITHOUT BURNING DOWN THE WHOLE BUILDING

Slide 69

Slide 69 text

Angular 2.0

Slide 70

Slide 70 text

AMPERSAND + REACT

Slide 71

Slide 71 text

BUT MODULARITY ISN’T THE ONLY FEATURE

Slide 72

Slide 72 text

ONE EXAMPLE OF WHY WE FORKED

Slide 73

Slide 73 text

SMARTER/STRICTER MODELS

Slide 74

Slide 74 text

var model = new Backbone.Model({ name: 'henrik' }); model.on('change:name', function () { console.log('new changed'); }); model.set({name: 'bob'}); Backbone Models

Slide 75

Slide 75 text

IF MODELS ARE OUR SOURCE OF TRUTH… WE WANT THEM TO BE MORE READABLE

Slide 76

Slide 76 text

YOU HAVE TO DEFINE WHAT YOU STORE

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

SESSION STATE: RELATED, NOT PERSISTED

Slide 79

Slide 79 text

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'}

Slide 80

Slide 80 text

GETTER/SETTER TRANFORMATIONS

Slide 81

Slide 81 text

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}

Slide 82

Slide 82 text

CACHED, OBSERVABLE DERIVED PROPERTIES

Slide 83

Slide 83 text

var Person = AmpState.extend({ props: { name: 'string' }, derived: { nickName: { deps: ['name'], fn: function () { return this.name.slice(0, 3); } } } });

Slide 84

Slide 84 text

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'

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

READ MORE IN DOCS http://ampersandjs.com

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

MODULES ALL THE WAY DOWN™

Slide 89

Slide 89 text

WHAT ABOUT UNDERSCORE?

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

HOW MANY OF THOSE USE ONE OR TWO METHODS?

Slide 92

Slide 92 text

INCONSEQUENTIAL WHEN SERVER-SIDE

Slide 93

Slide 93 text

…OR WHEN BUILDING A CLIENTSIDE APP WITH IT

Slide 94

Slide 94 text

BUT FEELS UNNECESSARY WHEN WRITING CLIENTSIDE LIBRARIES

Slide 95

Slide 95 text

IF I’M WANTING A SINGLE FUNCTION THEN WHAT?

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

CROSS-BROWSER? NO UPSTREAM BUG FIXES

Slide 98

Slide 98 text

WHAT ABOUT JQUERY?

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

INDIVIDUALLY INSTALLABLE CROSS-BROWSER TESTED API NEVER UPDATED STRICT SEMVER

Slide 101

Slide 101 text

addClass(el, 'class1') addClass(el, 'class1', 'class2') addClass(el, [array of classes]) SUPPORTED APIS:

Slide 102

Slide 102 text

1.X.X API FOREVER

Slide 103

Slide 103 text

LODASH?

Slide 104

Slide 104 text

VERSIONED TOGETHER

Slide 105

Slide 105 text

PREPARE THE TOMATOES AGAIN…

Slide 106

Slide 106 text

No content

Slide 107

Slide 107 text

MAINTAINING PILES OF TINY MODULES IS A GIANT PAIN

Slide 108

Slide 108 text

"Another flaw in the human character is that everybody wants to build and nobody wants to do maintenance." - Kurt Vonnegut

Slide 109

Slide 109 text

1. SINGLE GITHUB REPO 2. CONTAINING 40+ MODULES 3. WRITE DOC 4. WRITE IMPLEMENTATION 5. WRITE TEST 6. RUN BUILD

Slide 110

Slide 110 text

CROSS-BROWSER TESTED WITH CI SYSTEM IE6+ using Travis CI + SauceLabs

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

npm i --save amp-x

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

THE VIEW LAYER IS THE HARDEST

Slide 115

Slide 115 text

Philip Roberts JS Slinger Extraordinaire @philip_roberts

Slide 116

Slide 116 text

SHARE SOME R+D

Slide 117

Slide 117 text

TEMPLATING ON THE SERVER IS EASY TO GROK

Slide 118

Slide 118 text

BUT NOW WE’RE MUTATING STATE

Slide 119

Slide 119 text

DOM IS STATEFUL WE HAVE TO SYNC OUR STATE WITH ACTUAL DOM STATE

Slide 120

Slide 120 text

No content

Slide 121

Slide 121 text

JEREMY CALLED IT…

Slide 122

Slide 122 text

"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

Slide 123

Slide 123 text

CURRENT DOM:

hi!

TARGET DOM:

Slide 124

Slide 124 text

THE SIMPLE WAY: // assume we have 'el' element // with this HTML: // "
" // we can just replace its contents // with a new string: el.innerHTML = "

hi!

"

Slide 125

Slide 125 text

IF INFREQUENT AND SIMPLE IT WORKS FINE

Slide 126

Slide 126 text

NOT IDEAL FOR LARGER SECTIONS OF DOM OR IF USER INPUTS NEEDS TO MAINTAIN FOCUS

Slide 127

Slide 127 text

WHAT IF WE COULD DO THIS? mutateElement(el, "

hi!

");

Slide 128

Slide 128 text

.mutateElement() WOULD DO THIS: var pTag = document.createElement('p'); pTag.textContent = "hi!" el.appendChild(pTag);

Slide 129

Slide 129 text

THEN WE ONLY UPDATE WHAT’S ACTUALLY DIFFERENT

Slide 130

Slide 130 text

NO THRASHING DOM WITHOUT REASON

Slide 131

Slide 131 text

IF DOM ALREADY MATCHES IT DOES NOTHING

Slide 132

Slide 132 text

DOM DIFFING™

Slide 133

Slide 133 text

DOM DIFFING™

Slide 134

Slide 134 text

IF WE COULD DO THIS WITH HIGH PERFORMANCE BINDINGS BECOME SIMPLER

Slide 135

Slide 135 text

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

Slide 136

Slide 136 text

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 (

{this.model.name}

) } });

Slide 137

Slide 137 text

DOWNSIDES: THEIR TEMPLATING THEIR VIRTUAL DOM THEIR APP PATTERNS

Slide 138

Slide 138 text

CAN WE JUST STEAL THEIR BEST IDEAS?

Slide 139

Slide 139 text

WHAT IF WE COULD DO IT WITH HTML STRINGS?

Slide 140

Slide 140 text

THEN WE COULD GENERATE HTML USING ANY TEMPLATE LIBRARY!

Slide 141

Slide 141 text

1. PARSE HTML INTO SOME SORT 
 OF "AST" OR VIRTUAL DOM

Slide 142

Slide 142 text

2. DIFF THAT "AST" AGAINST THE LAST ONE

Slide 143

Slide 143 text

3. GENERATE A SET OF DOM TRANSFORMS FROM THAT DIFF

Slide 144

Slide 144 text

4. APPLY THEM TO THE DOM

Slide 145

Slide 145 text

THESE ARE ALL "SOLVED PROBLEMS"

Slide 146

Slide 146 text

BIG QUESTION IS PERFORMANCE

Slide 147

Slide 147 text

EVERYONE KNOWS YOU SHOULDN’T WRITE AN HTML PARSER

Slide 148

Slide 148 text

…ESPECIALLY WITH REGEX

Slide 149

Slide 149 text

No content

Slide 150

Slide 150 text

YES… BUT…

Slide 151

Slide 151 text

BUT WE’RE NOT PARSING ARBITRARY HTML, WE’RE PARSING HTML WE CONTROL

Slide 152

Slide 152 text

A FEW SIMPLIFYING ASSUMPTIONS AND WE CAN DO IT, QUITE WELL

Slide 153

Slide 153 text

{{ DEMO }}

Slide 154

Slide 154 text

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

Slide 155

Slide 155 text

1. SIMPLER VIEWS 2. LESS BINDINGS 3. EASIER TO GROK WHAT’S THE ACUTAL VALUE?

Slide 156

Slide 156 text

INITIAL FINDINGS: 1. ~SAME PERFORMANCE AS REPLACE 2. FILESIZE: 7.25kb min + gzip 3. NESTED VIEW COMPONENTS WORK 4. CHOICE OF TEMPLATING LANGUAGE

Slide 157

Slide 157 text

A VIEW MIXIN WORKS WITH BACKBONE + AMPERSAND

Slide 158

Slide 158 text

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

Slide 159

Slide 159 text

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

Slide 160

Slide 160 text

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

Slide 161

Slide 161 text

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

Slide 162

Slide 162 text

POTENTIAL OTHER THINGS? Simpler serverside rendering Do parsing in a web-worker?

Slide 163

Slide 163 text

LET’S WORK TOWARD A MORE FLEXIBLE AND DECOUPLED FUTURE

Slide 164

Slide 164 text

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

Slide 165

Slide 165 text

THANKS! @HenrikJoreteg, andyet.com