Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Feel the Glimmer - ParisJS
Search
Marco Otte-Witte
November 29, 2017
Programming
1
530
Feel the Glimmer - ParisJS
An intoduction to Ember.js' Glimmer VM VM and Glimmer.js
Marco Otte-Witte
November 29, 2017
Tweet
Share
More Decks by Marco Otte-Witte
See All by Marco Otte-Witte
Securing Technology Investments
marcoow
0
210
Handling images on the web
marcoow
0
410
SSR, SPAs and PWAs
marcoow
0
350
Fast, Fast, Fast
marcoow
2
500
Feel the Glimmer - MunichJS 11/17
marcoow
0
140
The JSON:API spec
marcoow
3
1.8k
Leveraging the complete Ember Toolbelt
marcoow
0
380
Feel the Glimmer
marcoow
1
240
Templates and Logic in Ember
marcoow
0
780
Other Decks in Programming
See All in Programming
アメ車でサンノゼを走ってきたよ!
s_shimotori
0
220
ALL CODE BASE ARE BELONG TO STUDY
uzulla
22
5.6k
Flutterで分数(Fraction)を表示する方法
koukimiura
0
130
Catch Up: Go Style Guide Update
andpad
0
230
Le côté obscur des IA génératives
pascallemerrer
0
150
Devoxx BE - Local Development in the AI Era
kdubois
0
130
Railsだからできる 例外業務に禍根を残さない 設定設計パターン
ei_ei_eiichi
0
880
Cursorハンズオン実践!
eltociear
2
1.1k
Software Architecture
hschwentner
6
2.3k
Claude Agent SDK を使ってみよう
hyshu
0
240
詳しくない分野でのVibe Codingで困ったことと学び/vibe-coding-in-unfamiliar-area
shibayu36
3
5k
Go Conference 2025: Goで体感するMultipath TCP ― Go 1.24 時代の MPTCP Listener を理解する
takehaya
9
1.7k
Featured
See All Featured
Building Adaptive Systems
keathley
44
2.8k
Learning to Love Humans: Emotional Interface Design
aarron
274
41k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
BBQ
matthewcrist
89
9.8k
Statistics for Hackers
jakevdp
799
220k
A Modern Web Designer's Workflow
chriscoyier
697
190k
The Language of Interfaces
destraynor
162
25k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Testing 201, or: Great Expectations
jmmastey
45
7.7k
Docker and Python
trallard
46
3.6k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
9
870
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
35
6.1k
Transcript
Feel the Glimmer
Marco Otte-Witte @marcoow
simplabs.com @simplabs
None
None
https://glimmerjs.com
"light-weight UI components for the web"
https://github.com/emberjs/ember.js/issues/13949
https://worldvectorlogo.com/logo/react
<ul> {this.props.people.map(function(person) { return <li>{person}</li>; })} </ul> ['Dan Abramov', 'Ben
Alpert'] { type: 'ul', props: { 'class': 'list' }, children: [ { type: 'li', props: {}, children: ['Dan Abramov'] }, { type: 'li', props: {}, children: ['Ben Alpert'] } ] }
+ { type: 'ul', props: { 'class': 'list' }, children:
[ + { type: 'li', props: {}, children: ['Dan Abramov'] } + { type: 'li', props: {}, children: ['Ben Alpert'] } + ]}
<ul> {this.props.people.map(function(person) { return <li>{person}</li>; })} </ul> ['Dan Abramov', 'Yehuda
Katz'] { type: 'ul', props: { 'class': 'list' }, children: [ { type: 'li', props: {}, children: ['Dan Abramov'] }, { type: 'li', props: {}, children: ['Yehuda Katz'] } ] }
+ { type: 'li', props: {}, children: ['Yehuda Katz'] }
- { type: 'li', props: {}, children: ['Ben Alpert'] }
The Glimmer Pipeline 1. Pre-Compilation 2. Initial render 3. Re-render
Pre-Compilation Templates are pre-compiled (at build time) into opcodes that
the Glimmer VM executes during initial render
<ul class="nav nav-tabs"> <li class="active"> <a href="/home">{{home}}</a> </li> <li> <a
href="/profile">{{profile}}</a> </li> <li> <a href="/messages">{{messages}}</a> </li> </ul>
[ [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] ]
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 ............ ...
Initial render DOM elements are created and opcodes for re-renders
are generated
[ [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] ]
<ul class="nav nav-tabs"> <li class="active"> <a href="/home">Start</a> </li> <li> <a
href="/profile">Profil</a> </li> <li> <a href="/messages">Nachrichten</a> </li> </ul>
<ul class="nav nav-tabs"> <li class="active"> <a href="/home">{{home}}</a> </li> <li> <a
href="/profile">{{profile}}</a> </li> <li> <a href="/messages">{{messages}}</a> </li> </ul> only these can change at all
[ ["OPTIMIZED-CAUTIOUS-UPDATE", "home"], ["OPTIMIZED-CAUTIOUS-UPDATE", "profile"], ["OPTIMIZED-CAUTIOUS-UPDATE", "messages"] ]
Update Renders Update opcodes are executed
let foo = 1; let fooReference: Reference<number> = { value()
{ return foo; } }; fooReference.value(); // => 1 foo++; fooReference.value(); // => 2
let foo = 1; let bar = 2; let fooReference:
Reference<number> = { value() { return foo; } }; let barReference: Reference<number> = { value() { return bar; } }; let fooPlusBarReference: Reference<number> = { value() { return fooReference.value() + barReference.value(); } }; fooPlusBarReference.value(); // => 3 foo = 2; fooPlusBarReference.value(); // => 4
interface EntityTag<T> { value(): T; validate(ticket: T): boolean; } interface
Tagged { tag: EntityTag<any>; } interface TaggedReference<T> extends Reference<T>, Tagged { }
const person: TrackedObject = { tag: new DirtyableTag(), name: 'Godfrey
Chan' }; let nameReference: VersionedReference<string> { 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
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 } } }
http://yehudakatz.com/2017/04/05/the-glimmer-vm-boots-fast-and-stays-fast/
http://yehudakatz.com/2017/04/05/the-glimmer-vm-boots-fast-and-stays-fast/
The Glimmer VM was released with Ember.js 2.10
"Stability without Stagnation"
None
https://glimmerjs.com https://glimmerjs.com
» ls -lh 514K ember-data.prod.js 1.6M ember.prod.js 1.1K react-dom.js 644K
react.js
None
None
None
Like React, Glimmer.js is only the "V" and some of
the "C" in "MVC" (aka components)
npm install -g ember-cli ember new my-app -b @glimmer/blueprint cd
my-app/ && ember s
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 ...
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 ...
https://github.com/Microsoft/TypeScript/issues/1375
<ul id="todo-list" class="todo-list"> {{#each visibleTodos key="_id" as |todo|}} <TodoItem @todo={{todo}}
@onEdit={{action editTodo}} @onToggle={{action toggleTodo}} @onDestroy={{action removeTodo}} /> {{/each}} </ul>
@tracked('todos') get activeTodos() { return this.todos.filter(todo => !todo.completed) }
Demo https://github.com/glimmerjs/todomvc-demo
Try it yourself! http://try.glimmerjs.com
Ember's Future
Where does this leave Ember.js?
https://emberjs.com/blog/2017/04/05/emberconf-2017-state-of-the-union.html
None
None
None
saved time and money
cp -r glimmer-app/src/ui/components ember-app/src/ui
ember-router will be the next thing to be extracted into
it's own standalone library
https://glimmerjs.com
https://www.dotjs.io
Thanks
Q&A
simplabs.com @simplabs