Slide 1

Slide 1 text

Feel the Glimmer

Slide 2

Slide 2 text

Marco Otte-Witte @marcoow

Slide 3

Slide 3 text

simplabs.com @simplabs

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

https://glimmerjs.com

Slide 7

Slide 7 text

"light-weight UI components for the web"

Slide 8

Slide 8 text

https://github.com/emberjs/ember.js/issues/13949

Slide 9

Slide 9 text

https://worldvectorlogo.com/logo/react

Slide 10

Slide 10 text

    {this.props.people.map(function(person) { return
  • {person}
  • ; })}
['Dan Abramov', 'Ben Alpert'] { type: 'ul', props: { 'class': 'list' }, children: [ { type: 'li', props: {}, children: ['Dan Abramov'] }, { type: 'li', props: {}, children: ['Ben Alpert'] } ] }

Slide 11

Slide 11 text

+ { type: 'ul', props: { 'class': 'list' }, children: [ + { type: 'li', props: {}, children: ['Dan Abramov'] } + { type: 'li', props: {}, children: ['Ben Alpert'] } + ]}

Slide 12

Slide 12 text

    {this.props.people.map(function(person) { return
  • {person}
  • ; })}
['Dan Abramov', 'Yehuda Katz'] { type: 'ul', props: { 'class': 'list' }, children: [ { type: 'li', props: {}, children: ['Dan Abramov'] }, { type: 'li', props: {}, children: ['Yehuda Katz'] } ] }

Slide 13

Slide 13 text

+ { type: 'li', props: {}, children: ['Yehuda Katz'] } - { type: 'li', props: {}, children: ['Ben Alpert'] }

Slide 14

Slide 14 text

The Glimmer Pipeline 1. Pre-Compilation 2. Initial render 3. Re-render

Slide 15

Slide 15 text

Pre-Compilation Templates are pre-compiled (at build time) into opcodes that the Glimmer VM executes during initial render

Slide 16

Slide 16 text

Slide 17

Slide 17 text

[ [6,"ul"], [9,"class","nav nav-tabs"], [7] [0," \n "], [6,"li"], [9,"class","active"], [7], [0,"\n "], [6,"a"], [9,"href","/home"], [7], [1, [18,"home"], false ], [8], [0,"\n "], [8], … [0,"\n"], [8] ]

Slide 18

Slide 18 text

Offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 19 01 00 00 1F 00 16 01 01 00 20 00 16 01 02 00 .......... ..... 00000010 19 01 03 00 1F 00 16 01 04 00 04 01 00 00 05 01 ................ 00000020 05 00 18 01 00 00 16 01 06 00 20 00 16 01 02 00 .......... ..... 00000030 19 01 07 00 30 00 04 01 00 00 05 01 08 00 3D 02 ....0.........=. 00000040 00 00 18 00 01 01 01 00 31 00 10 01 08 00 1D 03 ........1....... 00000050 09 00 00 00 00 00 1F 00 16 01 0A 00 20 00 14 00 ............ ...

Slide 19

Slide 19 text

Initial render DOM elements are created and opcodes for re-renders are generated

Slide 20

Slide 20 text

[ [6,"ul"], [9,"class","nav nav-tabs"], [7] [0," \n "], [6,"li"], [9,"class","active"], [7], [0,"\n "], [6,"a"], [9,"href","/home"], [7], [1, [18,"home"], false ], [8], [0,"\n "], [8], … [0,"\n"], [8] ]

Slide 21

Slide 21 text

Slide 22

Slide 22 text

only these can change at all

Slide 23

Slide 23 text

[ ["OPTIMIZED-CAUTIOUS-UPDATE", "home"], ["OPTIMIZED-CAUTIOUS-UPDATE", "profile"], ["OPTIMIZED-CAUTIOUS-UPDATE", "messages"] ]

Slide 24

Slide 24 text

Update Renders Update opcodes are executed

Slide 25

Slide 25 text

let foo = 1; let fooReference: Reference = { value() { return foo; } }; fooReference.value(); // => 1 foo++; fooReference.value(); // => 2

Slide 26

Slide 26 text

let foo = 1; let bar = 2; let fooReference: Reference = { value() { return foo; } }; let barReference: Reference = { value() { return bar; } }; let fooPlusBarReference: Reference = { value() { return fooReference.value() + barReference.value(); } }; fooPlusBarReference.value(); // => 3 foo = 2; fooPlusBarReference.value(); // => 4

Slide 27

Slide 27 text

interface EntityTag { value(): T; validate(ticket: T): boolean; } interface Tagged { tag: EntityTag; } interface TaggedReference extends Reference, Tagged { }

Slide 28

Slide 28 text

const person: TrackedObject = { tag: new DirtyableTag(), name: 'Godfrey Chan' }; let nameReference: VersionedReference { tag: person.tag, value() { return person.name; } }; nameReference.value(); // => 'Godfrey Chan' nameReference.tag.value(); // => 1 person.name = 'Yehuda Katz'; nameReference.tag.validate(1); // => false nameReference.value(); // => 'Yehuda Katz' nameReference.tag.value(); // => 2

Slide 29

Slide 29 text

class UpdateOpcode { execute() { if (!this.reference.tag.validate(this._lastTag)) { this._lastTag = this.reference.tag.value(); let newValue = this.reference.value(); this.domNode.textContent = newValue; // update DOM } } }

Slide 30

Slide 30 text

http://yehudakatz.com/2017/04/05/the-glimmer-vm-boots-fast-and-stays-fast/

Slide 31

Slide 31 text

http://yehudakatz.com/2017/04/05/the-glimmer-vm-boots-fast-and-stays-fast/

Slide 32

Slide 32 text

The Glimmer VM was released with Ember.js 2.10

Slide 33

Slide 33 text

"Stability without Stagnation"

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

https://glimmerjs.com https://glimmerjs.com

Slide 36

Slide 36 text

» ls -lh 514K ember-data.prod.js 1.6M ember.prod.js 1.1K react-dom.js 644K react.js

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

Like React, Glimmer.js is only the "V" and some of the "C" in "MVC" (aka components)

Slide 41

Slide 41 text

npm install -g ember-cli ember new my-app -b @glimmer/blueprint cd my-app/ && ember s

Slide 42

Slide 42 text

tree . my-app !"" config # !"" environment.js # !"" module-map.ts # $"" resolver-configuration.ts !"" dist/ !"" src # !"" ui # # !"" components # # # $"" my-app # # # !"" component.ts # # # $"" template.hbs # # !"" styles # # # $"" app.css # # $"" index.html # !"" index.ts # $"" main.ts !"" ember-cli-build.js # ... other files ...

Slide 43

Slide 43 text

tree . my-app !"" config # !"" environment.js # !"" module-map.ts # $"" resolver-configuration.ts !"" dist/ !"" src # !"" ui # # !"" components # # # $"" my-app # # # !"" component.ts # # # $"" template.hbs # # !"" styles # # # $"" app.css # # $"" index.html # !"" index.ts # $"" main.ts !"" ember-cli-build.js # ... other files ...

Slide 44

Slide 44 text

https://github.com/Microsoft/TypeScript/issues/1375

Slide 45

Slide 45 text

    {{#each visibleTodos key="_id" as |todo|}} {{/each}}

Slide 46

Slide 46 text

@tracked('todos') get activeTodos() { return this.todos.filter(todo => !todo.completed) }

Slide 47

Slide 47 text

Demo https://github.com/glimmerjs/todomvc-demo

Slide 48

Slide 48 text

Try it yourself! http://try.glimmerjs.com

Slide 49

Slide 49 text

Ember's Future

Slide 50

Slide 50 text

Where does this leave Ember.js?

Slide 51

Slide 51 text

https://emberjs.com/blog/2017/04/05/emberconf-2017-state-of-the-union.html

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

saved time and money

Slide 56

Slide 56 text

cp -r glimmer-app/src/ui/components ember-app/src/ui

Slide 57

Slide 57 text

ember-router will be the next thing to be extracted into it's own standalone library

Slide 58

Slide 58 text

https://glimmerjs.com

Slide 59

Slide 59 text

https://www.dotjs.io

Slide 60

Slide 60 text

Thanks

Slide 61

Slide 61 text

Q&A

Slide 62

Slide 62 text

simplabs.com @simplabs