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

Javascript, как создать свободный цикл анимации выделения, чтобы избежать сбора мусора?

Я пытаюсь создать плавный цикл javascript для анимации обоев на 60 кадров в секунду. Я заметил, что сборщик мусора запускает и добавляет переменное ненулевое время в рамки анимации. Я начал с отслеживания распределения в моем коде, а затем изолировал цикл. Я использовал requestAnimationFrame и обнаружил, что в якобы "пустой" петле. Он по-прежнему вызывает распределение каждой итерации и запускает сборщик мусора. Разочарочно это, похоже, происходит и в других механизмах цикла setInterval и setTimeout.

Ниже я собрал несколько jsfiddles и скриншотов, демонстрирующих образец "пустые циклы". Все образцы составляют от ~ 5 секунд.

В этот момент я ищу лучшее решение для минимизации сбора мусора. Из приведенных ниже образцов выглядит так: requestAnimationFrame - худший вариант в этом отношении.

requestAnimationFrame

https://jsfiddle.net/kevzettler/e8stfjx9/

var frame = function(){
    window.requestAnimationFrame(frame);
};

window.requestAnimationFrame(frame);

введите описание изображения здесь

setInterval

https://jsfiddle.net/kevzettler/p5LbL1am/

var frame = function(){
   //literally nothing
};

window.setInterval(frame, 0);

введите описание изображения здесь

SetTimeout

https://jsfiddle.net/kevzettler/9gcs6gqp/

var frame = function(){
    window.setTimeout(frame, 0);
}

window.setTimeout(frame, 0);

введите описание изображения здесь

4b9b3361

Ответ 1

На самом деле я не уверен, но, похоже, я помню, что у веб-работников есть свои сборщики мусора, и поэтому GC-удар не повлияет на FPS в основном потоке (хотя это все равно повлияет на способность обновлений к основной теме)

Ответ 2

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

Как и предполагалось, выделение объекта "Число" для каждого вызова будет связано с сбором мусора.

https://bugs.chromium.org/p/chromium/issues/detail?id=120186#c20

Он также предположил, что просто наличие открытой отладки записи трассировки стека может вызвать проблемы. Интересно, является ли это тем же самым случаем при удаленной отладке?

Этот ответ предлагает flip flopping между кадрами анимации, чтобы уменьшить сбор мусора: fooobar.com/info/75599/...

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

Мы должны помнить, что мы не стремимся избегать сбор мусора полностью, так как он настолько фундаментален для JS. Вместо этого мы стремясь максимально уменьшить его, чтобы кадры с 16 мс (для получения 60 кадров в секунду).

Один из подходов VelocityJs состоит в том, чтобы иметь один глобальный "тик", который обрабатывает всю анимацию...

Таймеры создаются, когда setInterval(), setTimeout() и requestAnimationFrame(). Есть две проблемы с производительностью с созданием таймера: 1) слишком много выстрелов таймеров сразу уменьшает рамку тарифы из-за чрезмерных расходов браузеров на их сохранение, и 2) неправильно отмечая время начала анимации сброшенных кадров.

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

http://www.sitepoint.com/incredibly-fast-ui-animation-using-velocity-js/

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

https://www.scirra.com/blog/76/how-to-write-low-garbage-real-time-javascript