Подтвердить что ты не робот

Контролируйте и точно определите, как долго отображается изображение

Для изучения времени реакции (см. также этот вопрос, если вам интересно), мы хотим контролировать и измерять время отображения изображений. Мы хотели бы учитывать время, необходимое для перерисовки на компьютерах разных пользователей.

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

Позже я нашел событие MozAfterPaint ". Для работы на компьютерах пользователей требуется изменение конфигурации, и соответствующий WebkitAfterPaint не сделал этого. Это означает, что я не могу использовать его на компьютерах пользователей, но я использовал его для собственного тестирования. Я вставил соответствующие фрагменты кода и результаты моих тестов ниже.
Я также вручную проверил результаты с SpeedTracer в Chrome.

// from the loop pre-rendering images for faster display
var imgdiv = $('<div class="trial_images" id="trial_images_'+i+'" style="display:none"><img class="top" src="' + toppath + '"><br><img class="bottom" src="'+ botpath + '"></div>');
Session.imgs[i] = imgdiv.append(botimg);
$('#trial').append(Session.imgs);

// in Trial.showImages
$(window).one('MozAfterPaint', function () {
    Trial.FixationHidden = performance.now();
});
$('#trial_images_'+Trial.current).show(); // this would cause reflows, but I've since changed it to use the visibility property and absolutely positioned images, to minimise reflows
Trial.ImagesShown = performance.now();

Session.waitForNextStep = setTimeout(Trial.showProbe, 500); // 500ms    

// in Trial.showProbe
$(window).one('MozAfterPaint', function () {
    Trial.ImagesHidden = performance.now();
});
$('#trial_images_'+Trial.current).hide();
Trial.ProbeShown = performance.now();
// show Probe etc...

Результаты сопоставления длительностей, измеренных с помощью MozAfterPaint и встроенного исполнения.

Это не делает меня слишком счастливым. Во-первых, средняя продолжительность отображения составляет около 30 мс короче, чем хотелось бы. Во-вторых, дисперсия с использованием MozAfterPaint довольно велика (и больше, чем для встроенного исполнения), поэтому я не могу просто настроить ее, увеличив значение setTimeout на 30 мс. В-третьих, это на моем довольно быстром компьютере, результаты для других компьютеров могут быть хуже.

Boxplot of durations

Relationship of durations measured using two methods

Результаты SpeedTracer

Это было лучше. Время, когда изображение было видимым, обычно находилось в пределах 4 (иногда) 10 мс предполагаемой продолжительности. Также было похоже, что Chrome учитывает время, необходимое для перерисовки в вызове setTimeout (поэтому между вызовом была разница 504ms, если изображение нужно перерисовать). К сожалению, я не смог анализировать и отображать результаты для многих испытаний в SpeedTracer, потому что он только регистрируется для консоли. Я не уверен, что расхождение между SpeedTracer и MozAfterPaint отражает различия в двух браузерах или что-то, чего не хватает в моем использовании MozAfterPaint (я уверен, что правильно интерпретировал вывод SpeedTracer).

Вопросы

Я хотел бы знать

  • Как я могу измерить время, которое он был фактически видимым на пользовательском компьютере, или хотя бы получить сопоставимые номера для набора разных браузеров на разных тестовых компьютерах (Chrome, Firefox, Safari)?
  • Можно ли компенсировать время рендеринга и рисования, чтобы достигнуть 500 мс фактической видимости? Если мне приходится полагаться на универсальное смещение, это было бы хуже, но все же лучше, чем показывать изображения на такой короткий срок, что пользователи не видят их сознательно на несколько медленных компьютерах.
  • Мы используем setTimeout. Я знаю о requestAnimationFrame, но, похоже, мы не можем получить какие-либо преимущества от его использования:
    Предполагается, что исследование будет сосредоточено на протяжении всего исследования, и более важно, чтобы мы отображали +/- 500 мс, чем определенное количество кадров в секунду. Правильно ли я понимаю?

Очевидно, что Javascript не идеален для этого, но он наименее плох для наших целей (исследование должно запускаться в режиме онлайн на собственных компьютерах пользователей, попросив их установить что-то, напугало бы некоторых из них, Java не поставляется в Mac OS X браузеры).
Мы разрешаем использовать только текущие версии Safari, Chrome, Firefox и, возможно, MSIE (обнаружение функции для API производительности и полного экрана, я еще не проверял, как MSIE) на данный момент.

4b9b3361

Ответ 1

Потому что я еще не получил еще ответов, но многому научился при редактировании этого вопроса, я публикую свой прогресс в качестве ответа. Как вы увидите, это все еще не оптимально, и я с радостью награду щедрости всем, кто улучшит его.

Статистика

New results

  • В самой левой панели вы можете увидеть распределение, которое заставило меня усомниться в оценках времени, которые я получал.
  • Средняя панель показывает, что я сделал после кеширования, переупорядочивая некоторые вызовы, используя несколько цепочек, минимизируя переходы, используя visibility и абсолютное позиционирование вместо display.
  • Самая правая панель показывает, что я получил после использования адаптированной функции Joe Lambert, используя requestAnimationFrame. Я сделал это после чтения blogpost о rAF, теперь с точностью до миллисекунды тоже. Я думал, что это только поможет мне сгладить анимацию, но, судя по всему, она помогает и в улучшении фактических продолжительности отображения.

Результаты

В итоговой панели среднее значение времени "краска-краска" составляет ~ 500 мс, среднее значение для встроенного тайминга выполнения реалистично сказывается (имеет смысл, потому что я использую одну и ту же метку времени для завершения внутреннего цикла ниже) и коррелирует с графиком "краска-краска".

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

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

window.requestTimeout, используя window.requestAnimationFrame

window.requestTimeout = function(fn, delay) {
    var start = performance.now(),
        handle = new Object();
    function loop(){
        var current = performance.now(),
            delta = current - start;

        delta >= delay ? fn.call() : handle.value = window.requestAnimationFrame(loop);
    };
    handle.value = window.requestAnimationFrame(loop);
    return handle;
};

Edit:

An ответьте на другой мой вопрос на ссылку хорошая новая статья.

Ответ 2

Вы пытались получить начальные миллисекунды, а после того, как событие запущено, вычислите разницу? вместо setTimeout. что-то вроде:

var startDate = new Date();
var startMilliseconds = startDate.getTime();

// when the event is fired :
(...), function() {
    console.log(new Date().getTime() - startMilliseconds);
});

старайтесь избегать использования jQuery, если это возможно. простой JS даст вам лучшее время отклика и лучшую общую производительность.