la ember.js meetup, jan 2017
TRANSCRIPT
January 2017
twitter.com/mixonic
Ember.js Core Team
madhatted.com
FORMALISM
1 let spaceship = { 2 mass: 2 3 }; 4 5 let acceleration = 2; 6 let force = spaceship.mass * acceleration; 7 8 accelerate(spaceship, force);
1 let spaceship = { 2 mass: 2 3 }; 4 5 function deriveForce(mass, acceleration) { 6 return mass * acceleration; 7 } 8 9 let acceleration = 2; 10 let force = deriveForce(spaceship.mass, acceleration); 11 12 accelerate(spaceship, force);
“The purpose of abstraction is not to be vague, but to create a new semantic level in
which one can be absolutely precise.”
The Humble Programmer Edsger Dijkstra 1972
1 let spaceship = { 2 mass: 2 3 }; 4 5 function deriveForce(mass, acceleration) { 6 return mass * acceleration; 7 } 8 9 let acceleration = 2; 10 let force = deriveForce(spaceship.mass, acceleration); 11 12 accelerate(spaceship, force);
INTUITION
We now come to the decisive step of mathematical abstraction: we forget about what the symbols stand for.
The mathematician is concerned with the catalogue alone; he is like the man in the catalogue room who does not
care what books or pieces of an intuitively given manifold the symbols of his catalogue denote. He need
not be idle; there are many operations which he may carry out with these symbols, without ever having to
look at the things they stand for.
The Mathematical Way of Thinking Hermann Weyl 1940
20172011 2013 2015
1.0 2.0
WHO USES THE WEB
AND HOW
0
0.25
0.5
0.75
1
2011 2012 2013 2014 2015 2016
Global Desktop Web Traffic
Global Mobile Web Traffic
StatsCounter
ITU
WHAT THE WEB IS
0
0.25
0.5
0.75
1
2011 2012 2013 2014 2015 2016
Chrome Traffic
IE Traffic
StatsCounter
• Online/Offline status • Selection API • XHR2 / CORS • background-color: currentColor • All ES5 • let / const • High Resolution Timers • MessageChannel • Blobs • TypedArrays • Geolocation • Web Sockets
IE11+ WEB FEATURES
• Online/Offline status • Selection API • XHR2 / CORS • background-color: currentColor • All ES5 • let / const • High Resolution Timers • MessageChannel • Blobs • TypedArrays • Geolocation • Web Sockets
• Web Workers • Internationalization API • Strict HTTPS Transport • HTTP2 • MP3, AAC, MPEG-4/H.264 • WOFF • SVG, SVG filters • <input pattern= • DNS prefetch • Multiple File Selection • Viewport sizes (8vw) • querySelector, matches
IE11+ WEB FEATURES
• Online/Offline status • Selection API • XHR2 / CORS • background-color: currentColor • All ES5 • let / const • High Resolution Timers • MessageChannel • Blobs • TypedArrays • Geolocation • Web Sockets
• Web Workers • Internationalization API • Strict HTTPS Transport • HTTP2 • MP3, AAC, MPEG-4/H.264 • WOFF • SVG, SVG filters • <input pattern= • DNS prefetch • Multiple File Selection • Viewport sizes (8vw) • querySelector, matches
• File API • IndexedDB • WebGL • dataset • <script> defer • getBoundingClientRect • ::first-line • calc() • requestAnimationFrame • atob / btoa • PageTransitionEvent • <video>
IE11+ WEB FEATURES
• Online/Offline status • Selection API • XHR2 / CORS • background-color: currentColor • All ES5 • let / const • High Resolution Timers • MessageChannel • Blobs • TypedArrays • Geolocation • Web Sockets
• Web Workers • Internationalization API • Strict HTTPS Transport • HTTP2 • MP3, AAC, MPEG-4/H.264 • WOFF • SVG, SVG filters • <input pattern= • DNS prefetch • Multiple File Selection • Viewport sizes (8vw) • querySelector, matches
• File API • IndexedDB • WebGL • dataset • <script> defer • getBoundingClientRect • ::first-line • calc() • requestAnimationFrame • atob / btoa • PageTransitionEvent • <video>
• <audio> • Session History • <progress> • MutationObserver • Navigation Timing API • <script> async • naturalWidth, naturalHeight • input event • matchMedia • crypto.getRandomValues() • Viewport sizes (8vw) • classList
IE11+ WEB FEATURES
• Online/Offline status • Selection API • XHR2 / CORS • background-color: currentColor • All ES5 • let / const • High Resolution Timers • MessageChannel • Blobs • TypedArrays • Geolocation • Web Sockets
• Web Workers • Internationalization API • Strict HTTPS Transport • HTTP2 • MP3, AAC, MPEG-4/H.264 • WOFF • SVG, SVG filters • <input pattern= • DNS prefetch • Multiple File Selection • Viewport sizes (8vw) • querySelector, matches
• File API • IndexedDB • WebGL • dataset • <script> defer • getBoundingClientRect • ::first-line • calc() • requestAnimationFrame • atob / btoa • PageTransitionEvent • <video>
• <audio> • Session History • <progress> • MutationObserver • Navigation Timing API • <script> async • naturalWidth, naturalHeight • input event • matchMedia • crypto.getRandomValues() • Viewport sizes (8vw) • classList
• Custom events • TTF/OTF • CSP 1.0 • Range • page visibility • SVG in CSS background • 3d transforms • Semantic Elements, e.g. <section> • AppCache • Web Crypto • CSS3 multi-column layout • console log methods
• insertAdjacentHTML • Session History
IE11+ WEB FEATURES
WHO DEVELOPS FOR THE WEB
0
32500
65000
97500
130000
2011 2013 2015
BLS
Fulltime Web Developers, USA
2011
2017
• Make Ember easier to learn • Deliver it to clients in smaller, smarter chunks • Do less work on the client • Better arrange work on the client • Make it easier for addons and contributors to participate
INITIATIVESThe Road Ahead
ENGINES & LAZY LOADING
• emberjs/rfcs#10 Merged in April 2016 • Design cycle was 1.5 years! • Additions to Ember were kept minimal, the majority of the
functionality is in the ember-engines addon • Further specification for lazy loading in emberjs/rfcs#153
(asset manifest) and emberjs/rfcs#158 (loader service) • Support for lazy loading is in [email protected]
MODULE UNIFICATION
• Proceeded by emberjs/rfcs#124, Module Normalization • emberjs/rfcs#143 Merged in mid-October • Design cycle was 8 months • Included building a migration tool for real apps to test our
assumptions about aesthetics (ember-module-migrator) • Work on a dynamic version of the resolver begun in ember-
cli/ember-cli#6332 • Work on improving IDE support in emberjs/ember.js#14430
JAVASCRIPT MODULE API
• emberjs/rfcs#176 opened November 2016, closed 5 days ago
• Based on feedback from “module shims”, emberjs/rfcs#68 • Includes plans for a migration tool via static analysis • Was considered for 2.12, but we decided to go slow
ROUTER SERVICE
• emberjs/rfcs#95 was merged November 2016 • Design cycle a little over a year • There have been several partial implementations, but no
complete PR
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <div {{my-element-modifier}}></div>
1 <my-ember-component />
GLIMMER COMPONENTS & ELEMENT MODIFIERS
• emberjs/rfcs#60 (Component Unification) closed April • emberjs/rfcs#112 (Element Modifiers) open since January • Challenges:
• Moving from this.attrs to this.args. New two way binding callback API • If we migrate to this.args, what happens to the name `didReceiveAttrs` • Is there a better way to express recompilation than observers? • DOM attributes and props • @arg
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <my-ember-component> 2 Hello 3 </my-ember-component>
1 <my-ember-component class="important"> 2 Hello 3 </my-ember-component>
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <my-ember-component 2 class="important" 3 data-priority> 4 Hello 5 </my-ember-component>
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <div> 2 {{@model.name}} 3 </div>
1 <my-ember-component 2 class="important" 3 data-priority 4 @model={{someProperty}} />
1 <div class="important" data-priority> 2 Mitchell 3 </div>
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <div> 2 {{@model.name}} 3 </div>
1 <my-ember-component 2 class="important" 3 data-priority 4 @model={{someProperty}} />
1 <div class="important" data-priority> 2 Mitchell 3 </div>
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <div> 2 {{@model.name}} 3 </div>
1 <my-ember-component 2 class="important" 3 data-priority 4 @model={{someProperty}} />
1 <div class="important" data-priority> 2 Mitchell 3 </div>
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <div> 2 {{@model.name}} 3 </div>
1 <my-ember-component 2 class="important" 3 data-priority 4 @model={{someProperty}} />
1 <div class="important" data-priority> 2 Mitchell 3 </div>
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <div class="solid"> 2 {{@model.name}} 3 </div>
1 <div class="important solid"> 2 Mitchell 3 </div>
1 <my-ember-component 2 class="important" 3 @model={{someProperty}} />
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <div class="solid"> 2 {{@model.name}} 3 </div>
1 <div class="important solid"> 2 Mitchell 3 </div>
1 <my-ember-component 2 class="important" 3 @model={{someProperty}} />
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <my-ember-component 2 @model={{someProperty}} as |name|> 3 {{name}} 4 </my-ember-component>
1 <div> 2 {{yield @model.name}} 3 </div>
1 <div> 2 Mitchell 3 </div>
GLIMMER COMPONENTS & ELEMENT MODIFIERS
1 <my-ember-component 2 @model={{someProperty}} as |name|> 3 {{name}} 4 </my-ember-component>
1 <div> 2 {{yield @model.name}} 3 </div>
1 <div> 2 Mitchell 3 </div>
GLIMMER COMPONENTS & ELEMENT MODIFIERS
IGNITER
• No RFC yet. Experimentation in runspired/igniter • Would remove the requirement of explicit runloops
IGNITER
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
render(); render(); render();
IGNITER
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
render(); render(); render();
IGNITER
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
scheduleRender(); scheduleRender(); scheduleRender();
IGNITER
Ember.run(() => { 2 3 4 });
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
scheduleRender(); scheduleRender(); scheduleRender();
IGNITER
Ember.run.begin(); 2 3 4 Ember.run.end();
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
scheduleRender(); scheduleRender(); scheduleRender();
IGNITER
Ember.run.begin(); 2 3 4 Ember.run.end();
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
scheduleRender(); scheduleRender(); scheduleRender();
render();
IGNITER
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
scheduleRender(); scheduleRender(); scheduleRender();
IGNITER
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
scheduleRender(); scheduleRender(); scheduleRender();
1 setTimeout(() => { 2 render(); 3 });
IGNITER
IGNITER
1 obj.set('name', 'Betsy'); 2 obj.set('age', '42'); 3 obj.set('shoes', 'heels');
scheduleRender(); scheduleRender(); scheduleRender();
1 requestAnimationFrame(() => { 2 render(); 3 });
• Glimmer binary VM and wire format, stack VM • Interoperability with ES Classes • Lazy evaluation and dead code elimination • Fastboot rehydration • Critical path rendering • Improved RFC automation • Improved visibility of feature progress
The Future
“…is already here —”
William Gibson 1999
“it’s just not evenly distributed”
William Gibson 1999
“It is hard for people to imagine what the web is capable of.”
201 Created Clients 2017
shop-201.com
• SEO Friendly • Great animations • Install-to-homescreen • Tap-to-pay (ApplePay) • Phones, tablets,
desktops
Thanks