1

Я строю тестовую платформу для конкурса производительности JavaScript. Одна из задач позволяет участникам оптимизировать код JavaScript, отвечающий за обработку анимации холста. После отправки решения сервер запускает его с помощью phantomjs и считывает среднее число FPS после 20 секунд анимации. Проблема в том, что я получаю 3-4FPS для оптимизированного и неоптимизированного кода. Это делает невозможным определить, был ли улучшен код.Программно измерять производительность анимации холста

Пар фактов:

  • Я 100% уверен, что phanotmjs правильно рендеринг анимации (сделано несколько скриншотов)
  • в браузере неоптимизированного коде работает на 13FPS, оптимизированные бега на 58FPS
  • phantomjs не поддерживает requestAnimationFrame поэтому мне пришлось использовать polyfill
  • Я использую этот код, приведенный ниже, чтобы проверить количество РЗУ

frameCounter.js

var frameCounter = (function() { 
    var frames = 0; 
    var startTime = new Date(); 

    function bump() { 
     frames++; 
     window.requestAnimationFrame(bump); 
    } 

    bump(); 

    return { 
     getFPS: function() { 
      var time = (new Date() - startTime)/1000; 

      return (frames/time).toPrecision(4); 
     } 
    } 
})(); 

Мой вопрос: как я могу программно измерить производительность холста анимации?

+0

Так phantomjs использует 'setTimeout' в то время как ваш браузер имеет фактическую' функцию requestAnimationFrame'? – Bergi

+0

Выполняет ли ваша функция 'bump' реальную работу, или это просто счетчик для измерения производительности без анимации? – Bergi

+0

@Bergi Да, phantomjs использует 'setTimeout', в то время как браузер использует' requestAnimationFrame'. Тем не менее, я заставил браузер использовать polyfill, а количество FPS все еще было намного выше для оптимизированного кода, чем для не оптимизированного. –

ответ

2

Поскольку phantomjs не может произвести более 3-4 FPS для любой анимации, я в конечном итоге использовал «настоящий» браузер для этой задачи. Я смог автоматизировать его благодаря Chrome remote debugging protocol.

Я сделал Node.js приложение, которое каждый раз был новый код, чтобы проверить, сделал следующие шаги:

  • подключен к вкладке в браузере Chrome (браузер должен быть запущен с флагом --remote-debugging-port=9222)
  • навигация вкладка на тестовой странице
  • оценивали код внутри вкладки, которые пытались вынести 300 кадров анимации так быстро, как это возможно
  • возвратил время выполнения

Вот отрывок из моего кода:

//connect to a tab (you can find <tab-debug-id> on http://localhost:9222/json page) 
var ws = new WebSocket("ws://localhost:9222/devtools/page/<tab-debug-id>"); 

ws.onerror = function() { 
    //handle error 
}; 

ws.onopen = function() 
{ 
    //when connection is opened hard reload the page before we start 
    ws.send(JSON.stringify({ 
     id: 1, 
     method: "Page.reload", 
     params: { 
      ignoreCache: true 
     } 
    })); 
}; 

ws.onmessage = function (evt) 
{ 
    var data = JSON.parse(evt.data); 

    if(data.id === 1) { 
     //reload was successful - inject the test script 
     setTimeout(function(){ 
      ws.send(JSON.stringify({ 
       id: 2, 
       method: "Runtime.evaluate", 
       params: { 
       expression: '(' + injectedCode.toString() + '());' 
       } 
      })); 
     }, 1000); 
    } else if(data.id === 2) { 
     //animation has finished - extract the result 
     var result = data.result.result.value; 
    } 
}; 
0

вы можете использовать Date.now(), чтобы сократить время, затрачиваемое на создание объекта, он должен улучшить точность по крайней мере немного

+0

Я не ищу микро-улучшения моего кода, извините. Основная проблема заключается в том, что метод, который я сейчас использую для измерения FPS, не является надежным и дает одинаковые результаты как для оптимизированного, так и для неоптимизированного кода. –

3

Я написал небольшой скрипт, несколько месяцев назад специально для измерения FPS и потребления для requestAnimationFrame.

Я не уверен, что это поможет вам на 100%, но может дать вам хороший указатель.

Meter snap

Использование довольно прост:

  • Инициализировать счетчик где-то в коде перед цикл, в котором вы указываете элемент DIV для использования в качестве измерителя
  • Убедитесь, что вы захватить аргумент заданный requestAnimationFrame, так как это укажет, сколько времени потрачено (если не будет отложено использование метода даты/времени).
  • Простой вызов его метода с помощью этого аргумента.

Зеленый цвет указывает, что вы работаете в оптимальном режиме FPS (в большинстве случаев 60). Желтый означает, что цикл потребляет больше, чем приблизительные 16,7 мс, и скорость снижается примерно до половины. Оранжевый означает, что вы используете более чем вдвое больше бюджета и так далее.

Счетчик использует взвешенные FPS, чтобы дать вам более точное измерение.

Пример:

var meter = new animMeter('divElementId'); 

function animate(timeArg) { 

    /// funky stuff here 

    meter.update(timeArg); 

    requestAnimationFrame(animate); 
} 

A demo of this in action can be found here.

Вы найдете код самого измерителя почти в нижней части, предварительно сведенной к минимуму. Не стесняйтесь копировать и вставлять. Он поставляется с лицензией MIT.

И как всегда при использовании таких метров: они будут потреблять несколько миллисекунд сами, чтобы обновить графику, чтобы ввести крошечный запас ошибки.

Еще одна вещь, о которой нужно знать, - это то, что rAF всегда будет работать, пытаясь достичь 60 FPS, поэтому счетчик никогда не сможет измерить более высокие частоты кадров, чем это.

Если вам нужно измерить более высокие частоты кадров, вы можете вызвать метод обновления без аргументов и использовать setTimeout вместо rAF, и он будет использовать дату/время для измерения производительности - немного более неточно, но вы можете получить более высокие номера FPS (это произвольные кадры, так как монитор не может отображать больше кадров, чем он синхронизирован в любом случае .. обычно 60 кадров в секунду).

+0

Спасибо за советы. Анимированный счетчик FPS отлично смотрится, но мне нужно это среднее значение FPS за 20 секунд анимации, напечатанное на моей консоли. Вероятно, я могу захватить часть вашего кода, который измеряет FPS и пытается использовать его, но я не могу найти неминифицированную версию вашего кода. Он доступен где-то? –

+0

@ KonradDzwinel Конечно, вот полный источник: http://pastebin.com/ZJHNVTi5. У нас уже есть код усреднения по строке 127, просто протяните одну секунду до 20 секунд. – K3N

Смежные вопросы