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 - MunichJS 11/17
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Marco Otte-Witte
November 02, 2017
Programming
0
150
Feel the Glimmer - MunichJS 11/17
An intoduction to Ember.js' Glimmer VM VM and Glimmer.js
Marco Otte-Witte
November 02, 2017
Tweet
Share
More Decks by Marco Otte-Witte
See All by Marco Otte-Witte
Securing Technology Investments
marcoow
0
240
Handling images on the web
marcoow
0
430
SSR, SPAs and PWAs
marcoow
0
360
Fast, Fast, Fast
marcoow
2
510
Feel the Glimmer - ParisJS
marcoow
1
540
The JSON:API spec
marcoow
3
1.8k
Leveraging the complete Ember Toolbelt
marcoow
0
400
Feel the Glimmer
marcoow
1
250
Templates and Logic in Ember
marcoow
0
810
Other Decks in Programming
See All in Programming
余白を設計しフロントエンド開発を 加速させる
tsukuha
7
2.1k
今から始めるClaude Code超入門
448jp
7
8.4k
Amazon Bedrockを活用したRAGの品質管理パイプライン構築
tosuri13
4
250
AgentCoreとHuman in the Loop
har1101
5
220
例外処理とどう使い分ける?Result型を使ったエラー設計 #burikaigi
kajitack
16
6k
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
380
組織で育むオブザーバビリティ
ryota_hnk
0
170
コマンドとリード間の連携に対する脅威分析フレームワーク
pandayumi
1
450
AIと一緒にレガシーに向き合ってみた
nyafunta9858
0
170
CSC307 Lecture 06
javiergs
PRO
0
680
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
100
AI Schema Enrichment for your Oracle AI Database
thatjeffsmith
0
250
Featured
See All Featured
Why Our Code Smells
bkeepers
PRO
340
58k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
0
140
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
130
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
930
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Embracing the Ebb and Flow
colly
88
5k
The Spectacular Lies of Maps
axbom
PRO
1
520
How to make the Groovebox
asonas
2
1.9k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
300
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.3k
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'] } ] }
<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 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
<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 set(person, 'name', 'Yehuda Katz'); nameReference.tag.validate(1); // => false nameReference.value(); // => 'Yehuda Katz' nameReference.tag.value(); // => 2
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|}} <todo-item @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
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.youtube.com/watch?v=62xd25kEZ3o&t=27617s
Thanks
Q&A
simplabs.com @simplabs