$30 off During Our Annual Pro Sale. View Details »

Feel the Glimmer - ParisJS

Feel the Glimmer - ParisJS

An intoduction to Ember.js' Glimmer VM VM and Glimmer.js

Marco Otte-Witte

November 29, 2017
Tweet

More Decks by Marco Otte-Witte

Other Decks in Programming

Transcript

  1. Feel the Glimmer

    View Slide

  2. Marco Otte-Witte
    @marcoow

    View Slide

  3. simplabs.com
    @simplabs

    View Slide

  4. View Slide

  5. View Slide

  6. https://glimmerjs.com

    View Slide

  7. "light-weight UI components for the web"

    View Slide

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

    View Slide

  9. https://worldvectorlogo.com/logo/react

    View Slide


  10. {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'] }
    ] }

    View Slide

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

    View Slide


  12. {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'] }
    ] }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide



  16. {{home}}


    {{profile}}


    {{messages}}


    View Slide

  17. [
    [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]
    ]

    View Slide

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

    View Slide

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

    View Slide

  20. [
    [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]
    ]

    View Slide



  21. Start


    Profil


    Nachrichten


    View Slide



  22. {{home}}


    {{profile}}


    {{messages}}


    only these can change at all

    View Slide

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

    View Slide

  24. Update Renders
    Update opcodes are executed

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  29. 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
    }
    }
    }

    View Slide

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

    View Slide

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

    View Slide

  32. The Glimmer VM was released with
    Ember.js 2.10

    View Slide

  33. "Stability without Stagnation"

    View Slide

  34. View Slide

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

    View Slide


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

    View Slide

  37. View Slide

  38. View Slide

  39. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide


  45. {{#each visibleTodos key="_id" as |todo|}}
    @onEdit={{action editTodo}}
    @onToggle={{action toggleTodo}}
    @onDestroy={{action removeTodo}} />
    {{/each}}

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  49. Ember's Future

    View Slide

  50. Where does this leave Ember.js?

    View Slide

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

    View Slide

  52. View Slide

  53. View Slide

  54. View Slide

  55. saved time and money

    View Slide

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

    View Slide

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

    View Slide

  58. https://glimmerjs.com

    View Slide

  59. https://www.dotjs.io

    View Slide

  60. Thanks

    View Slide

  61. Q&A

    View Slide

  62. simplabs.com
    @simplabs

    View Slide