Что сделать для ускорения логики реализованной на jQuery?
Ситуация такая. На сайте есть возможность управления видимостью элементов в зависимости от состояния других элементов. Т.е. пометил чекбокс - появился дополнительный блок, убрал с него checked - блок пропал + все элементы в нём очистились.
Пока целевых блоков было 5-10, всё ОК, но админы быстро захотели запихать туда 100-200 и стало заметно тормозить при переключении. Всё там реализовано на довольно сложных селекторах, вызовах closest(), $.each, jQuery.inArray, данные хранятся в data-showhide- атрибутах. Т.е. jQuery используется активно.
Попробовал переписать все $.each на нативные JS циклы, выигрыш 1%-2% плюс код стал менее читабельным, вернули назад. Попробовали минимизировать количество вызовов $ и по максимуму использовать нативные JS объекты, тоже не более 5% выигрыша + усложнение восприятия кода.
Кто подскажет, есть-ли какие неявные моменты, которые в jQuery кушают производительность? Ведь не может цикл перебора максимум тысячи элементов так серьёзно кушать ресурсы.
мистер, вы упороты. любая манипуляция с DOM сравнима с операциями Input\Output , что, как бы намекает, не переборщи. а 250 зависимостей это как раз тот случай когда переборщил. джквери парсит строку запроса потом просто делает запросы getElementBy.... , тоесть тут не зарыто клада оптимизации. тормозит - убери без чего мож обойтись. не можешь обойтись-смирись.
@Pavel_Osipov 5 это не 250. навскидку до 50 еще както жить можно. но вот 250... я даже ситуации такой не могу себе представить где оно может пригодиться...
Да. Аппетит у админов приходит во время еды. Хорошо хоть 250, это уже реально максимум. Ну да будем думать, в Хроме вон и 250 за пару секунд отрабатывают.
Ведь не может цикл перебора максимум тысячи элементов так серьёзно кушать ресурсы.
Если речь идет об обращениях к DOM, то может. Оптимизация в этом случае заключается в сокращении количества операций с DOM. Что именно можно сделать в вашем случае за глаза не скажешь.
Ну конкретного решения я и не просил. Просто предположил, что возможно есть какое-то удобство в jQuery от которого можно отказаться угоду производительности. Сам понимаю, что в jQuery по идее всё и так по возможности оптимизировано и тут надо в самом алгоритме менять что-то.
не обязательно на сами эдементы ссылки делать, можно на наборы элементов сразу, так сказать. То есть типа
var $el = $('selector')
и там уже будут готовые ссылки на объекты DOM, а не будет их при каждом вызове искать
У вас там очень много каскадных событий. Также в пиковых нагрузках присутствует обработка анимации, попробуйте вместо fadeIn/fadeOut простой hide/show.
Да, спасибо, так и сделал уже, красоту убрал, вместо
trgt_holder.fadeTo( "fast" , 0, function() {
просто
trgt_holder.css( 'display', 'none' );
теперь.
В принципе примерно на 20% быстрее стало.
Без каскадных событий никуда, там довольно сложные зависимости могут быть :)
Спасибо! Да, знаю, что CSS бывает аппаратно ускоренный. Но сейчас там из JS мы только и с .css( 'display','none') свойством работаю, считаете, что замена его на что-то типа .addClass( 'no_display') может дать прирост производительности?
Вообще, на данный момент я стал использовать requestAnimationFrame и всё стало заметно шустрее. На хроме так вообще летает :)
Посмотрите в сторону AngularJS, манипуляции с DOM он делает шустрее, то что вам нужно, можно без проблем на нем реализовать. Меньше кода и больше скорость работы.
Вот чтоб вам не искать angular.ru
Спасибо. Я сталкивался с этой штукой. В своё время выбирали между ним и knockout.js. Выбрали второй, так-как задача была небольшая, а есть мнение, что для небольших задач он лучше. Честно говоря, не очень я в восторге от knockout, да и angular много чаще упоминается последнее время на том же хабре.
Так-что спасибо за идею.
Вопрос такой, "шустрее", это на сколько?
Я тоже сначала начал использовать нокаут, но потом перешел на ангуляр. На сколько шустрее сказать не могу, тесты сам не писал, но ангуляр создан для таких задач, поэтому там все очень хорошо оптимизировано для работы с ДОМ.
Вы правы, прироста скорости в моей задаче с ним не получилось. Ну да, как я уже писал, у меня всё в производительность JQWidgets упёрлось, а их ковырять сейчас не резон
В итоге. Больше всего кушает производительность jQWidgets. При работе с нативными элементами, даже самый большой вариант с 250-ю элементами на старом IE8 обрабатывается не больше секунды.
Поэтому и оптимизации нашего кода выигрыша так мало давали, что не в нём затык. Ну и смысла на ангулар переписывать тоже нет в данном случае.
Хотя конечно Native DOM is fast!