Skip to content

Commit

Permalink
setTimeout(0) is faster than rAF
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Feb 26, 2014
1 parent 1a05dea commit 5100f3e
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/directives/repeat.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,11 @@ module.exports = {
if (this.queued) return
this.queued = true
var self = this
setTimeout(function () {
utils.nextTick(function () {
if (!self.compiler) return
self.compiler.parseDeps()
self.queued = false
}, 0)
})
},

/**
Expand Down
9 changes: 2 additions & 7 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@ var config = require('./config'),
join = [].join,
win = window,
console = win.console,

timeout = win.setTimeout,

This comment has been minimized.

Copy link
@bpierre

bpierre Feb 26, 2014

There is also window.setImmediate(f), which is only supported in Firefox and IE at the moment. Maybe this line could be replaced by:

    timeout   = win.setImmediate || win.setTimeout,

A strong polyfill here (with IE6-8 and NodeJS parts): https://github.com/NobleJS/setImmediate

Edit: it would be stupid to put win.setImmediate in a timeout var, but you get the idea :-)

This comment has been minimized.

Copy link
@yyx990803

yyx990803 Feb 27, 2014

Author Member

Hah, yeah I could take the postMessage part of the polyfill and test the results.
I used rAF thinking it would give better DOM rendering results, but accidentally using setTimeout showed substantial perf gain in the TodoMVC benchmark... now Vue is consistently faster than everything else in all browsers!

This comment has been minimized.

Copy link
@wryk

wryk Feb 27, 2014

timoxley/next-tick component ?

This comment has been minimized.

Copy link
@bpierre

bpierre Feb 27, 2014

I made a quick test on the benchmark with NobleJS/setImmediate:

  • A bit slower in Firefox (and I was wrong, setImmediate is not supported in Firefox yet)
  • Same results in Chrome

I haven’t try timoxley/next-tick though, but faster than anything else is not that bad for the moment, ha ha.

This comment has been minimized.

Copy link
@yyx990803

yyx990803 Feb 27, 2014

Author Member

Internally timoxley/next-tick is the same thing - they both use window.postMessage in Chrome and other recent browsers. I don't really see great benefits incorporating them if the results are the same.

This comment has been minimized.

Copy link
@stefanpenner

stefanpenner Apr 7, 2014

just a warning about using postMessage/setImmediate -> cujojs/when#197 As a result of this, all the promise implementations have switched to nextTick setTimeout or MutationObserver for next turn style functionality

When available a MutationObserver is the most stable/performant approach to nextTick in the browser.

hasClassList = 'classList' in document.documentElement,
ViewModel // late def

var defer =
win.requestAnimationFrame ||
win.webkitRequestAnimationFrame ||
win.setTimeout

var utils = module.exports = {

/**
Expand Down Expand Up @@ -195,7 +190,7 @@ var utils = module.exports = {
* used to defer batch updates
*/
nextTick: function (cb) {
defer(cb, 0)
timeout(cb, 0)
},

/**
Expand Down

3 comments on commit 5100f3e

@kristoferjoseph
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a change that should be reverted.
I may be way off base, and if so I apologize, but my understanding is:

setTimeout will fire at a given time based on the interval set, but takes no consideration as to where in the run loop the browser currently is.

rAF on the other hand fires at the beginning of every frame in sync with the run loop so you are guaranteed not to be running computation at a time that may eat into your page paint.

Jank happens when your code is running over the buffer allotted and starts to eat into the time the browser is trying to paint.

Basically your code will run "faster" in that it will not be burdened by the render cycle, but to an end user they will see less fluid updates because it is not able to repaint.

Twitter discussion on the matter

@yyx990803
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dam, I think you are right. I've also later found out that setTimeout appeared faster in the bench because the bench code clocked everything with setTimeout itself, and some non-javascript render time was not included in the time measured.

@kristoferjoseph
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yyx990803 So glad I wasn't out of line there. I only mentioned it because I really like VUE. Would be interesting to profile the TODO apps with something that takes this into account. I've found that once animations are added this tiny change makes a pretty significant difference to the end result being jank free.

Please sign in to comment.