Topics:
- what a Run Loop is?
- Why a Run Loop
- Run Loop Queues in Ember
- autoRun
- autoRun and Testing
- Other methods of Ember.run
Topics:
... not a loop
like programmers might think
for (i = 0; i < length; i++) { // some stuff here }
It is an 'aggregate changes over time' mechanism.
..used to batch, and order (or reorder) work in a way that is most ... efficient ... by scheduling work on specific queues. These queues have a priority,
and are processed to completion in priority order.
Queues are run in order of priority
Some things 'cost' more than others
Ineffective use of DOM calculations / layout
// assuming divs foo, bar, baz foo.style.height = "500px"; foo.offsetHeight;
bar.style.height = "400px"; foo.offsetHeight;
baz.style.height = "200px"; foo.offsetHeight;
Ineffective use of DOM calculations / layout
// assuming divs foo, bar, baz foo.style.height = "500px"; // write foo.offsetHeight; // read (recalculate style, layout)
bar.style.height = "400px"; // write foo.offsetHeight; // read (recalculate style, layout)
baz.style.height = "200px"; // write foo.offsetHeight; // read (recalculate style, layout)
Grouping writes before reads helps
// assuming divs foo, bar, baz foo.style.height = "500px"; // write bar.style.height = "400px"; // write baz.style.height = "200px"; // write foo.offsetHeight; // read (recalculate style, layout) bar.offsetHeight; // read (style and layout is already known) baz.offsetHeight; // read (style and layout is already known)
var Meetup = Ember.Object.extend({ title: 'Ember.js', location: 'SLC', food: 'pizza', prettyTitle: function() { return this.get('title') + ' - ' + this.get('location'); }.property('title', 'location'); });
{{location}} {{prettyTitle}}
var Meetup = Ember.Object.extend({ title: 'Ember.js', location: 'SLC', food: 'pizza', prettyTitle: function() { return this.get('title') + ' - ' + this.get('location'); }.property('title', 'location'); });
var meetup = Meetup.create(); meetup.set('location', 'PDX'); meetup.set('title', 'Emberenos');
var meetup = Meetup.create(); meetup.set('location', 'PDX'); // {{location}} and {{prettyTitle}} updated meetup.set('title', 'Emberenos'); // {{title}} and {{prettyTitle}} updated
var meetup = Meetup.create(); meetup.set('location', 'PDX'); meetup.set('title', 'Emberenos'); // {{location}}, {{title}} and {{prettyTitle}} updated
var meetup = Meetup.create(); meetup.set('location', 'PDX'); meetup.set('title', 'Emberenos'); meetup.set('location', 'SLC'); meetup.set('title', 'Ember.js'); // no DOM update
Ember.run.queues
sync
: synchonization jobs, propagate bound dataactions
: general work queue, scheduled tasks, promises, etcrouterTransitions
: routing transition jobsrender
: jobs meant for rendering, typically will update the DOMafterRender
: after the render is completedestroy
: jobs to finish tear-down objects other jobs have destroyed
QUEUE
with pending jobs = CURRENT_QUEUE
WORK_QUEUE
CURRENT_QUEUE
into WORK_QUEUE
WORK_QUEUE
In development and production Ember will automatically wrap code it finds in an autoRun
when appropriate
doSomething: function() { this.set('propA', 3); this.set('propB', 4); }
doSomething: function() { Ember.run.begin(); this.set('propA', 3); this.set('propB', 4); nextTick(function(){ Ember.run.end(); }); }
doSomething: function() { Ember.run(function() { this.set('propA', 3); this.set('propB', 4); }); }
Generally anything async that you write should consider the run loop.
Ember testing mode disables autoRun
Can cause testing issues if you are unaware of autoRun
Ember.run.join
Ember.run.later
<- use instead of setTimeout
Ember.run.next
<- next tick, consider schedule
Ember.run.schedule
<- push to queueEmber.run.throttle
plus more in Ember docs
thanks!