On to :-moz-any() selector grouping
On Sunday, somebody with the nickname {g}
was on irc.mozilla.org asking about the
behavior of setTimeout
.
In particular, he wanted to divide up work into a bunch of pieces in a
way that allowed the user to interact with the page while the work was
happening, and was doing this by doing a piece of the work, and then
making a setTimeout
call to continue the work. (In some cases, this
could also be done using workers.)
Unfortunately for him, setTimeout
in most browsers doesn't allow a delay
less than about 10 milliseconds (it forces any smaller delays to be
longer), so the work wasn't finishing as fast as it could. (Chrome has
changed this to 2 milliseconds, though, and apparently had some
problems with it.)
A while ago, Jeff Walden suggested to me that Web pages could get the
equivalent of setTimeout
, with a real zero delay, using postMessage
.
This turns out to be relatively straightforward:
// Only add setZeroTimeout to the window object, and hide everything // else in a closure. (function() { var timeouts = []; var messageName = "zero-timeout-message"; // Like setTimeout, but only takes a function argument. There's // no time argument (always zero) and no arguments (you have to // use a closure). function setZeroTimeout(fn) { timeouts.push(fn); window.postMessage(messageName, "*"); } function handleMessage(event) { if (event.source == window && event.data == messageName) { event.stopPropagation(); if (timeouts.length > 0) { var fn = timeouts.shift(); fn(); } } } window.addEventListener("message", handleMessage, true); // Add the one thing we want added to the window object. window.setZeroTimeout = setZeroTimeout; })();
I wrote a demo
page that demonstrates that this is significantly faster than
setTimeout(0)
. On a Firefox nightly 100 iterations of
setZeroTimeout
take about 10-20 milliseconds most of the
time, but occasionally longer; on a WebKit build I have it takes about
4-6 milliseconds, but occasionally a bit longer. (We should probably
investigate the performance difference here.) In comparison, in Firefox
and on non-Chromium-based WebKit, the setTimeout
version takes about a
second (though perhaps even longer on Windows).
Update (2010-03-12): My numbers were on Linux. Boris tells me that on Mac, it's the opposite: Gecko is faster than Safari or Chrome.