Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

JS тормоза

325
24 августа 2010 года
Franky
723 / / 10.08.2005
Всем привет! Давненько я не просил помощи у сообщества :)
На днях заболел очередной идеей, решил вспомнить ЯС и написать свой Арканоид (с блэкджеком и пр :) )
Но на стадии заготовки происходит неведомая фигня: в определенный момент (20-30 сек.) игра начинает резко тормозить.
http://yaweb.ru/test/2/index.html

Может кто сталкивался? В чем может быть проблема?

Браузер Опера (пользую как наиболее шустрый, но вроде и в остальных та же проблема)
Заранее спасибо!
244
24 августа 2010 года
UAS
2.0K / / 19.07.2006
Я, честно, хз, но может сделать
var ball = document.getElementById("ball")
один раз в глобальной видимости (и юзать ниже её), чем каждый раз вызывать метод (тем более два раза).
325
24 августа 2010 года
Franky
723 / / 10.08.2005
спасибо, но увы, не помогло. Да и этот тут на 99% не при чем
253
24 августа 2010 года
Proger_XP
1.5K / / 07.08.2004
Это из-за постоянного обновления экрана. Интервал в 3 мс - слишком маленький, таймеры в Windows имеют точность (resolution) 15 мс, то есть когда ты задаёшь таймер на 3 мс то реальная задержка получается либо 0, либо 15. Лучше сделать таймер где-то на 10-20 мс и добавить скорости шарику (он что-то очень медленно летает в любом случае).

Самое узкое место во всех браузерах - обновление изображения на экране, а у тебя это происходит каждые 0/15 мс - посчитай FPS, требуется много ресурсов.

Вывод профайлера в FF это подтверждает:
 
Код:
Функция                 Вызовов    Время
----------------------------------------
bmove                      1000   90.16%
onmousemove()                92    4.04%
getElementComputedStyle     184    3.54%
mouseLayerXY                 92    1.22%
checkPos                   1000    1.05%

Как видишь - checkPos() вызывалось столько же раз, сколько и bmove(), но т.к. там одни вычисления, то выполняется она очень быстро - даже при том, что кода в ней больше, чем в bmove().

На медленных машинах у тебя накапливаются вызовы setInterval() (т.к. bmove() не ждёт, пока отработает предыдущая) и в какой-то момент всё виснет. По этой причине я обычно использую setTimeout() и замеряю время, прошедшее с последнего события таймера, а отсюда уже строю прочие вычисления. И движение получается плавнее.
325
24 августа 2010 года
Franky
723 / / 10.08.2005
вау! Спасибо огромное! А где в фоксе такая фича?
Цитата:

он что-то очень медленно летает в любом случае


(с эстонским акцентом) этто пошаховая стратеххия
=)

253
24 августа 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: Franky
вау! Спасибо огромное! А где в фоксе такая фича?


Про Firebug не слышал? :) Первейшаая вещь для вебдева. Как откроешь консоль, сразу там кнопка будет.

Цитата:
(с эстонским акцентом) этто пошаховая стратеххия


Rofl :D

325
24 августа 2010 года
Franky
723 / / 10.08.2005
"Про Firebug не слышал? Первейшаая вещь для вебдева. "
знаю, пользуюсь, вчера специально искал в нем измерялку - не нашел :(
253
24 августа 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: Franky
"Про Firebug не слышал? Первейшаая вещь для вебдева. "
знаю, пользуюсь, вчера специально искал в нем измерялку - не нашел :(


Ну ты даёшь :)

325
24 августа 2010 года
Franky
723 / / 10.08.2005
еще раз спасибо!
*посыпаю голову пеплом*

п.с.: Кстати совет по скорости помог
285
24 августа 2010 года
Romik
479 / / 24.11.2002
Меня заинтересовал момент с таймерами. В моём проекте много анимации средствами js и порой начинает подтормаживать. После ряда оптимизаций с уменьшением размера картинок в момент анимации, работать стало существенно лучше. Но вот о том что дискретность таймеров может влиять на качество анимации догадывался, но серьёзно не задумывался. У меня не Windows, практически везде под проект используется Ubuntu. Потому хотелось бы услышать комментарий на этот счёт или хотя бы рекомендаций чего почитать по теме
253
24 августа 2010 года
Proger_XP
1.5K / / 07.08.2004
Честно говоря, не знаю, как в других ОС, но по-моему не стоит всерьёз расчитывать на то, что браузер сможет адекватно обновлять картинку и по ходу ещё выполнять скрипты каждые, например, 5 мс. А если анимации больше, чем одна, то такой интервал вполне может растянуться до 15-20 мс - особенно в FF и особенно в старых его версиях (1-2).
Хром в этом смысле намного лучше, ну, он под JS и заточен.

Поэтому я советую (1) использовать setTimeout вместо setInterval (и вызывать setTimeout после отработки функции таймера) и (2) строить расчёты не на задержке таймера, а на реально прошедшем времени, либо на оставшемся до завершении операции отрезке.
(2) поможет получить плавную анимацию даже на медленной машине/при тормозах браузера.

Рекомендовать к прочтению кроме гугла, увы, ничего не могу :)

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

SlideAs() просто обёртка для более удобного вызова Slide(). Использовать так:
 
Код:
// развернуть элемент, плавно меняя высоту и прозрачность, время выполнения - 1 сек.
SlideAs('height opacity', element, {maxDuration: 1000});

// свернуть, меняя длину, за 300 мс, с небольшим ускорением.
SlideAs('width', element, {maxDuration: 300, reverse: true, accel: true});

// сложный вариант, сразу оперирует над 2-мя разными жлементами.
Slide({element: el1, prop: 'opacity', maxDuration: 1000},
      {element: el2, prop: 'height', maxDuration: 500},
      {element: el2, prop: 'top', maxDuration: 500});


При вызовах можно задать больше опций, чем в примерах, см. SetupSlideOptions() - там они все устанавливаются.
Функции вроде $each(), $hide(), $style() говорят сами за себя и тривиальны, поэтому сюда не приложил.
563
24 августа 2010 года
MrLinker
249 / / 17.09.2006
Ух ты.
Я тоже когда-то пытался арканойдить:
http://mrlinker.narod.ru/arc/

Где-то еще была версия с вылетающими призами и разнотипными квадратиками, но не могу найти :)

В основном цикле тригонометрия не нужна.
Достаточно один раз, когда меняется угол, расчитать единичный вектор.
У меня там массив field позволяет нарисовать уровень.
285
24 августа 2010 года
Romik
479 / / 24.11.2002
Proger_XP, я пока пользуюсь jQuery().animate(), но назревает тот благородный момент, когда нужно что-то менять. И да, предварительно поразмыслив я сразу отказался от setInterval(), так как его сложно контролировать (требуются блокираторы навроде семафоров). setTumeout() куда проще в обращении. Я обернул всё в свой pushTimeout(func, time, group) и теперь группирую анимации.

В общем мне не хватало этих количественных размышлений об интервалах обновления. Спасибо.
253
24 августа 2010 года
Proger_XP
1.5K / / 07.08.2004
2Romik
Цитата:
(требуются блокираторы навроде семафоров)


Семафоры в JS... об этом надо написать статью :D

jQuery умеет уйму всего и всё уже отточено, но я предпочитаю писать всё сам, так интереснее.
Рад что смог помочь :)

325
26 августа 2010 года
Franky
723 / / 10.08.2005
как спасибу выкладываю что получилось на текущий момент:
http://yaweb.ru/test/2/index.html
старт/пауза - клик по полю.
Если работой не завалят - буду делать дальше блоки (разных ствойств) и бонусы. Как и что делать представляю, всё дело в "сесть и сделать" :)

п.с.: вопросом "на кой я это делаю?" задаюсь постоянно, но ответа пока не нашел. Если у кого будут какие-то мысли - пишите, хоть в ЛС.
п.п.с.: есть еще мечта переписать Тетрис...
253
26 августа 2010 года
Proger_XP
1.5K / / 07.08.2004
Вот эта версия мне же больше нравится, хорошая скорость и даже фон есть, а тормозов нет. Теперь даёшь блоки :)
Кстати, есть и глюк - после game over'а кликаешь ещё раз, появляется картика "Паука", клик - снова игровое окно, alert(game over), клик - "Пауза" и т.д. бесконечно.

Цитата: Franky

п.с.: вопросом "на кой я это делаю?" задаюсь постоянно, но ответа пока не нашел. Если у кого будут какие-то мысли - пишите, хоть в ЛС.


Для удовольствия и самообчения, зачем же ещё :)

325
26 августа 2010 года
Franky
723 / / 10.08.2005
Цитата:

Кстати, есть и глюк - после game over'а кликаешь ещё раз, появляется картика "Паука", клик - снова игровое окно, alert(game over), клик - "Пауза" и т.д. бесконечно.


это не бага, это фича ;)
Так и знал что кто-нибудь заметит. Кстати если подвести биту, то можно продолжать игру.
Естественно вместо алерта с гамовером будет обнуление счетчиков, позиций и пр. :)
Да, скорость реально исправилась во всех браузерах.

В общем буду делать и выкладывать сюда что получилось :)

325
30 августа 2010 года
Franky
723 / / 10.08.2005
обновил, ссылка выше.
призы (действующие), очки, жизни.
Раньше не мог достучаться до форума, лежал что ли?...
253
30 августа 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: Franky

Раньше не мог достучаться до форума, лежал что ли?...


Было дело. Майк наверное на CC10 уезжал и забрал с собой сервер :D

Арканоид кстати тормозить стал, даже больше, чем в первой версии.
Добавить бы сюда спецэффекты, как в версии MrLinker'а с jQuery :rolleyes:

325
30 августа 2010 года
Franky
723 / / 10.08.2005
н-да... делаю в Опере (там всё замечательно), теперь вижу косяки ИЕ и ФФ
по поводу анимации надо подумать, но получатся пересекающиеся таймеры, что не есть правильно.
253
30 августа 2010 года
Proger_XP
1.5K / / 07.08.2004
Цитата: Franky

по поводу анимации надо подумать, но получатся пересекающиеся таймеры, что не есть правильно.


В этом и соль :) Можешь попробовать сделать, как делают в играх - обновлять экран каждые N мсек, используя данные о перемещении объектов, вместо обновления экрана по ходу этого перемещения.

Не уверен правда, насколько это будет быстро в JS.

325
30 августа 2010 года
Franky
723 / / 10.08.2005
хм, мысля интересная, подумаю в этом направлении, хотя кажется что ничего не выйдет.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог