mathiasbynens/jsperf.com

Asynchronous preparation

Closed this issue · 4 comments

The scenario is simple - you need to run the test case where the preparation code is async. The real life example is - I want to test how the size of the image affects the speed of drawImage. In the preparation code I need to load few images and I can't start tests before they are loaded.
If I'm not missing something it will be nice to add the feature similar to the deferred.resolve(). If there's a already a way to do so - would be good to add to FAQ.

Can’t you just use <script> in the preparation HTML?

One example is worth thousand words :)

http://jsperf.com/draw-image/

In my preparation code I have the construction like this:

        var urls = [
            "http://juriy.com/img/tank_32_o.png",
            "http://juriy.com/img/tank_32_t.png",
            ...
            "http://juriy.com/img/empty.png"];

        var tank32o = preload(urls[0]);
        var tank32t = preload(urls[1]);
        ...

        var loadedCounter = 0;

        function preload(url) {
            var img = new Image();
            img.onload = function() {
                loadedCounter++;
                if (loadedCounter == urls.length) {
                    alert("Images loaded, ok to launch tests");
                }
            };

            img.onerror = function() {
                alert("Failed loading " + url + " tests can't run");
            };
            img.src = url;
            return img;
        }

(Just learned that alert doesn't work). Anyway, as you see, my preparation code starts several async tasks (loading sample images) and then returns. At this moment tests can already be launched, even though assets are not ready. So the tests will either fail or report wrong numbers. I assume that the same problem will happen with every test that depends on the external asset that is loaded in the asynchronous manner.

You could do:

// before async stuff
var run = document.getElementById('run');
run.innerHTML = 'Please wait…';
run.disabled = ui.running = true;

// then after it's done
run.disabled = ui.running = false;
ui.emit('complete');
run.innerHTML = 'Run tests';

Great hint, thanks!