JavaScript код бенчмаркинга заморозил браузер? - PullRequest
0 голосов
/ 29 марта 2012

Я создаю страницу для сравнения производительности кода платформы JavaScript. Вот одна из страниц http://qatrix.com/benchmark/set-css-style

Моя идея - использовать независимый iframe для независимого запуска кода, чтобы сделать его без конфликтов. Функция сравнения успешно запущена и может возвращать разумные результаты, но большая проблема для этой страницы сравнения состоит в том, что она временно замораживает веб-браузер, пока выполняется код, указывающий на курсор мыши, независимо от того, где и некоторые из эффектов при наведении мыши также недоступны.

Так в чем же проблема? И как это решить? Я вижу, что на некоторых веб-сайтах по бенчмаркингу нет этой проблемы, но они просто сравнивают код на той же странице, что, я думаю, будет с конфликтами.

Вот код запуска тестов под iframe:

var benchmark_code = function ()
{
    <?php echo $_GET['code'] ?>
},
benchmark = function(times)
{
    var start = new Date(),
        i, end;
    for( i = 0; i < times; i++) 
    {
        if( i == 0 )
        {
            try {
                benchmark_code.call();
            }
            catch (e)
            {
                return e;
            }
        }
        else
        {
            benchmark_code.call();
        }
    }
    end = new Date(); 
    return end - start;
};

А исходный код сравнительного анализа находится здесь (с использованием фреймворка Qatrix):

http://qatrix.com/js/benchmark.js

1 Ответ

0 голосов
/ 29 марта 2012

Javascript является однопоточным с пользовательским интерфейсом браузера. Во время выполнения javascript все остальные действия браузера ставятся в очередь в ожидании завершения потока javascript. Таким образом, пока ваш бенчмарк запущен, вы не сможете взаимодействовать со страницей.

Если вы рассчитываете каждый отдельный цикл вашего эталонного теста и суммируете эти времена (а не синхронизируете весь цикл), вы можете поддерживать работу браузера, выполняя каждый цикл с setTimeout(fn, 0). Это позволит браузеру обрабатывать ожидающие события между каждым циклом теста.

Вот способ выполнить этот тест асинхронно, чтобы браузер мог остаться в живых между запусками:

var benchmark = function(times, resultCallback) {
    var start, cum = 0, i = 0;

    function runOnce() {
         if (i++ < times) {
             start = new Date();
             benchmark_code.call();
             cum += new Date() - start;
             setTimeout(runOnce, 0);
         } else {
             resultCallback(cum);
         }
    }
    try {
        runOnce();
    } catch(e) {
        return e;
    }
};
...