Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   setInterval замедляется (https://javascript.ru/forum/events/85415-setinterval-zamedlyaetsya.html)

rgl 09.08.2023 15:22

setInterval замедляется
 
Такая ситуация. Открываю popup окно в котором должна быть анимация. Вызываю setInterval и все работает поначалу, но когда пытаюсь максимизировать popup окно, все многократно замедляется.
В чем тут проблема?
(браузер Edge)

Как-то так: http://dkirusfe.bget.ru/interval-test.html

voraa 09.08.2023 17:42

Когда вы максимизируете окно с движущимся квадратиком, основное окно становится невидимым, следовательно неактивным. Но таймер работает на основной вкладке. Для неактивных (минимизированных, неактивных вкладок) окон таймер автоматически замедляется до 1 сек.
https://usefulangle.com/post/280/set...n-inactive-tab
А в некоторых случаях даже до минуты
https://usefulangle.com/web-updates/...imers-1-minute

Aetae 09.08.2023 18:49

Ни и на будущее(текущей проблемы это не решит, см. причину выше) - для анимации следует использовать requestAnimationFrame чтобы работать напрямую с отрисовкой браузера, а не абстрактным таймером который ничего не гарантирует по определению.

voraa 09.08.2023 18:57

Aetae, requestAnimationFrame вроде тоже не будет срабатывать на неактивной вкладке

Aetae 09.08.2023 21:32

voraa, дык я уточнил в скобочках.)

rgl 14.08.2023 16:13

voraa,
Спасибо.

Aetae,
Спасибо за информацию, почитал, попробовал, могу немножко поспорить. setInterval ничего не гарантирует, но на практике в моем случае при интервеле 4ms и больше обновляет картинку примерно с заданной частотой, что меня устраивает c большим запасом. С другой стороны, requestAnimationFrame не позволяет задавать интервал (т.е. частоту), какая получится, такая и будет. В моем случае получается что-то примерно 16ms
requestAnimationFrame может быть полезна, напр, если надо добиться "плавности" движения, тогда, зная время, которое прошло с прошлого вызова, можно расчитать смещение. Но у меня задача другая, и в моем конкретном случае setInterval идеально подходит

rgl 14.08.2023 16:18

Форум не дает нажать плюсик, говорит "У Вас нет прав для выполнения этого действия. Пожалуйста, обновите страницу и войдите снова, прежде чем попробовать повторить действие."

ksa 14.08.2023 16:21

Цитата:

Сообщение от rgl
У Вас нет прав для выполнения этого действия

Проверь протокол - нужен https.

voraa 14.08.2023 16:55

Цитата:

Сообщение от rgl
но на практике в моем случае при интервеле 4ms и больше обновляет картинку примерно с заданной частотой, что меня устраивает c большим запасом. С другой стороны, requestAnimationFrame не позволяет задавать интервал (т.е. частоту), какая получится, такая и будет. В моем случае получается что-то примерно 16ms

Картинка все равно будет обновляться так, как она может. И именно requestAnimationFrame говорит: Выполни эту функцию перед очередным обновлением. От того, что поставить 4мс экран не будет обновлятться быстрее Если у вашего монитора частота 60Гц, то это как раз и будет 1/60 ~ 16.67 мс. Быстрее никак. Медленнее - может быть, если поток занят какой то тяжелой задачей, тогда очередное обновление будет только после ее окончания.

Борис К 15.08.2023 18:30

Цитата:

Сообщение от rgl
Форум не дает нажать плюсик, говорит "У Вас нет прав для выполнения этого действия. Пожалуйста, обновите страницу и войдите снова, прежде чем попробовать повторить действие."

Та же проблема!(((

Борис К 15.08.2023 18:32

Цитата:

Сообщение от ksa
Проверь протокол - нужен https.

Протокол https есть, а толку нет!(((

voraa 15.08.2023 19:34

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

ksa 16.08.2023 10:12

В тот момент, когда "не дает плюсануть", нужно проверить протокол... Просто дописать s и нажать Enter - тогда будет работать.

Правда будет еще одно ограничение - что-то типа "Вы уже плюсовали его, для его плюсования нужно сначала плюсануть кого-то еще". :D

rgl 16.08.2023 15:04

Цитата:

Сообщение от voraa (Сообщение 553015)
Картинка все равно будет обновляться так, как она может. И именно requestAnimationFrame говорит: Выполни эту функцию перед очередным обновлением. От того, что поставить 4мс экран не будет обновлятться быстрее Если у вашего монитора частота 60Гц, то это как раз и будет 1/60 ~ 16.67 мс. Быстрее никак. Медленнее - может быть, если поток занят какой то тяжелой задачей, тогда очередное обновление будет только после ее окончания.

Когда я говорил "успевает за 4ms" имел ввиду что при значениях 4 и больше функция вызывается (и успевает все сделать) примерно с соответствующей частотой. Понятно, что реально видимая картинка никак не может меняться чаще, чем частота монитора. Но вот вопрос - должна ли программа учитывать частоту монитора и работать по разному с разными мониторами? Однозначно ответить тут нельзя, у каждой точки зрения есть свои аргументы за и против.

Aetae 16.08.2023 15:23

rgl, ну на самом деле есть два аргумента, один из которых ультимативный: производить перерасчёт ровно столько раз сколько надо для установленной частоты - гораздо оптимальнее, чем делать это с заданным интервалом, в вашем случае выигрыш по ресурсам будет в 16/4 = 4 раза.
Второй аргумент, если интересно, это то, что таймер рассинхронизирован с кадрами, из-за чего может возникать пропуск кадра и небольшое дёрганье анимации.

voraa 16.08.2023 15:43

Цитата:

Сообщение от rgl
Но вот вопрос - должна ли программа учитывать частоту монитора и работать по разному с разными мониторами?

Да. Зачем делать лишние расчеты и изменения в DOM, которые все равно не будут визуализированы?

rgl 16.08.2023 15:55

Оба аргумента в некоторых случаях теряют силу. 4ms - это не рабочее значение а, как бы, проверка на прочность. Мне хотелось быть уверенным что производительности с запасом хватает.
А что если для моей задачи достаточно, скажем, 50 ms? По производительности никакого проигрыша, наоборот, в случае requestAnimationFrame мне нужно делать лишние действия - решать уже пора или еще нет. И дергание анимации может возникнуть, если оба числа близкие, напр. 16 и 20 или 16 и 10, а если они отличаются в разы (в любую сторону, то (с этой точки зрения!) все ОК. Скажем, задаю интервал 50 ms, ну иногда картинка будет меняться каждый пятый кадр, а иногда через 6. Никакого дергания.

rgl 16.08.2023 16:02

Цитата:

Сообщение от ksa (Сообщение 553028)
Правда будет еще одно ограничение - что-то типа "Вы уже плюсовали его, для его плюсования нужно сначала плюсануть кого-то еще". :D

И, похоже, не одного

voraa 16.08.2023 17:49

Цитата:

Сообщение от rgl
А что если для моей задачи достаточно, скажем, 50 ms? По производительности никакого проигрыша, наоборот, в случае requestAnimationFrame мне нужно делать лишние действия - решать уже пора или еще нет.

Если ваша задача занимает 50 мс, то обновление кадра произойдет через 50мс. Движок не прерывает выполнение задачи для визуализации очередного кадра. Есть четкий цикл выполнения
- Выполнение задачи,
- выполнение микрозадач,
-Если подошло время обновления кадра, то
- выполнение функции из requestAnimationFrame
- перерасчет стилей и компоновка
- визуализация кадра.

Под задачей понимается выполнение обработчиков событий и таймеров
Микрозадачи - выполнение функций исполненных промисов и обсерверов.
И пока задача не будет полностью выполнена, микрозадачи не начнут выполняться. Пока задачи и микрозадачи не будут исполнены, никаких действий по визуализации кадра не будет.

И, кстати, setInterval (f, 4) - не означает выполнить через 4 мс. Это означает поставить в очередь задач через 4 мс. Если в очереди уже есть задачи, которые в сумме выполняются 50мс, то значит функция будет выполнена через 50мс.


Часовой пояс GMT +3, время: 21:54.