SlideShare a Scribd company logo
Профилирование и оптимизация
        jQuery–кода

       Владимир Журавлев
Самый популярный фреймворк




По данным builtwith.com
Все любят jQuery
•   Простота и более низкий порог вхождения;
•   легко написать плохой код;
•   кроссбраузерный фасад для рутинных операций;
•   не все понимают, что происходит за этим фасадом;
•   «there is a jQuery plugin for it»;
•   значительная часть кода вам больше не принадлежит.
Профилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кода
•loop flipping;
•array-push-join вместо сложения строк;
•loop unrolling;
•{'Вася': 1, 'Коля': 1}[name]
•~~ (0.5 + n)
Преждевременная оптимизация
Преждевременная оптимизация
Симптомы:
•оптимизация кода еще до того как он начнет тормозить.

Последствия:
•потеря времени;
•ухудшение читаемости.
Экономия на спичках
Экономия на спичках
Симптомы:
•оптимизация частей кода, принципиально не влияющего на
производительность;
•автоматическое использование «оптимальных» конструкций.

Последствия:
•потеря времени;
•потеря читабельности;
•легко упустить настоящую оптимизацию.
Профилирование
Как измерять?
• Таймеры (например, сonsole.time);
• профилирование JS (Firebug, Web Inspector, YUI Profiler);
• анализ timeline (Web Inspector).
Таймеры
Зачем:
•убедиться, что данный блок кода тормозит;
•постоянно мониторить производительность модулей;
•быстро оценить успешность оптимизации.

Чем замерять:
•сonsole.time;
•любой самописный таймер.
сonsole.time
Использование

   console.time('init');


   /* блок измеряемого кода */


   console.timeEnd('init');
Профилирование JS
Зачем:
•для получения полного отчета о том на что тратит время ваш js код.

Чем профилировать:
•console.profile;
•YUI profiler;
•любой другой самописный профайлер.
console.profile
Достоинства:
•есть в Firebug, Chrome, Safari, IE 8+;
•достаточный минимум.

Недостатки:
•много шума при профилировании jQuery-кода;
•разные форматы отчетов.
console.profile
Использование

   console.profile('init');


   /* блок профилируемого кода */


   console.profileEnd('init');
Профилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кода
Профилирования и оптимизация jQuery-кода
YUI Profiler
Зачем:
•для браузеров, в которых нет профайлера;
•можно профилировать только обращения к jQuery.




developer.yahoo.com/yui/profiler
YUI Profiler
Использование:
   YAHOO.tool.Profiler.registerFunction('init', window);


   // профилируемый код
   init();


   var report = YAHOO.tool.Profiler.getFunctionReport('init');


   YAHOO.tool.Profiler.unregisterFunction('init');
YUI Profiler
Достоинства:
•работает везде;
•хорошо подходит для профилирования jQuery (например, можно
логировать только $.fn.*, $.*).

Недостатки:
•нельзя отличить $(selector) от $(html), $(element), $(function);
•логирует вложенные вызовы, что может искажать статистику;
•нет own time, только total time.
jquery.profile.js
Зачем:
•потому что велосипеды — это здорово;
•чтобы избавиться от недостатков YUI Profiler.

Плюсы:
•не логирует вложенные вызовы;
•раздельно логирует $(selector), $(html), $(function) и $(element).

github.com/private-face/jquery.profile
jquery.profile.js
Использование:
   var profiler = new $.Profiler;


   profiler.start();
   init();
   profiler.stop();


   profiler.topTime();
Профилирования и оптимизация jQuery-кода
jquery.profile.js
Недостатки:
•не логирует вложенные вызовы;
•«beta than nothing».
Анализ timeline
Зачем:
•чтобы определить как рендеринг влияет на производительность.

Что использовать:
•Chrome Web Inspector.
Профилирования и оптимизация jQuery-кода
Оптимизация
$('div').click(function() {
         var div = $(this);

        // ...
});

$('div').each(function() {
         var div = $(this);

        // ...
});
Селекторы
Симптомы:
•Большое число обращений к $(selector), $.fn.find, и т.п.
1. Селекторы разбираются cправа-налево

   $('div.post a.vote-up')    // плохо

   $('.post .vote-up');       // лучше

   $('.vote-up');             // еще лучше
2. Сужайте область поиска
•Задавайте контекст

   $('div.post a.vote-up');             // плохо
   $('#content').find('.vote-up');      // хорошо


•Используйте children, closest и т.п.

   $('ul#list').find('li');             // плохо
   $('ul#list').children('li');         // хорошо

   $('li').parents('div').first();      // плохо
   $('li').closest('div');              // хорошо
3. Кешируйте выборки и используйте chaining

   $('div.post').mousemove(function() ...);
   $('div.post').find('a').click(function() ...);   // плохо

   var posts = $('div.post');
   posts.mousemove(function() ...);
   posts.find('a').click(function() ...);           // хорошо

   $('div.post')
        .mousemove(function() ...)
        .find('a').click(function() ...)
        .end()
        .find('.invisible').hide();                 // тоже хорошо
4. Делегируйте обработку событий
•Избавьтесь от live. Совсем.

   $('a').live('click', function() {...                 // плохо

   $(document).on('click', 'a', function() {...         // супер


•Замените bind на on/delegate

   $('.vote').click(function() {...                     // плохо

   $('#content').on('click', '.vote', function() {...   // хорошо
Слишком много делегирования
Симптомы:
•задержка между событием и реакцией на него;
•большое количество вызовов $.fn.is в профайлере.

Оптимизация:
•отсекать лишние on/delegate;
•использование bind вместо on/delegate.
Повторяющиеся события
Симптомы:
•«тормоза» в момент ресайза, скролла или интенсивного ввода текста;
•профайлер показывает большое количество вызовов обработчиков
событий keydown, scroll, resize и т.п.

Оптимизация:
•Группировка нескольких вызовов события в один путем применения
декораторов debounce и throttle.
   benalman.com/projects/jquery-throttle-debounce-plugin/
debounce
$.debounce
•Группирует повторяющиеся события интервал между которыми меньше
определенного значения.

  события:

  обработчик:
throttle
$.throttle
•Группирует события которые были вызваны в пределах одного
интервала.

  события:

  обработчик:
Оптимизация $(element)
                 внутри each/map
Симптом:
•много времени тратится на $(element).

Оптимизация:
•использовать один общий jQuery–объект для всех элементов внутри
each/map;
•quickEach.
// создаем общий jQuery-объект за пределами map/each:
var a = $([0]);

$('a').each(function() {
         // подставляем текущий элемент в объект
         a[0] = this;

        // и используем его как обычный $(this)
        // ...
});
Недостаток:
•Нельзя использовать во вложенных асинхронных функциях.

   var a = $([0]);

   $('a').each(function() {
        a[0] = this;

         a.click(function() {
              // всегда будет выводиться текст последней ссылки
              alert(a.text());
         });
   });
Оптимизация создания элементов
Симптом:
•профайлер показывает, что много времени уходит на $(html), append,
prepend, before, after и т.п.
1. Клонирование быстрее создания
   // создание
   var soldiers = $.map(names, function(name) {
        return $('<div class="soldier"><span>' + name + '</span></div>');
   });

   // клонирование
   var bobaFett = $('<div class="soldier"><span>Boba</span></div>');
   var name = bobaFett.find('span');

   var soldiers = $.map(names, function(name) {
        name.text(name);
        return bobaFett.clone();
   });
2. Минимизируйте число операций вставки в DOM
   // вставка сразу после создания
   $.each(messages, function(_, text) {
        $('#history').append('<div class="message">' + text + '</div>');
   });

   // вставка пакетом
   var fragment = $(document.createDocumentFragment());

   $.each(messages, function(_, text) {
        fragment.append('<div class="message">' + text + '</div>');
   });
   $('#history').append(fragment);
Restyle, layout, paint
Restyle:
•пересчет стилей не меняющих геометрию объектов.
Layout:
•пересчет геометрии.
Paint:
•перерисовка после пересчета свойств и геометрии.
Restyle, layout, paint
• Время restyle, layout, paint сильно зависит от разметки;
• изменения откладываются на потом;
• иногда браузер вынужден применить изменения досрочно:
   –   offsetTop/Left/Width/Height
   –   scrollTop/Left/Width/Height
                                               jQuery.fn.css
   –   clientTop/Left/Width/Height
   –   getComputedStyle(), currentStyle [IE]
$('div').click(function() {
    var e = $(this);

      e.css('color', e.css('backgroundColor'));

      e.css('width', 100);

      e.css('font-size', 20);

      return false;
});
$('div').click(function() {
    var e = $(this);

      e.css('width', 100);

      e.css('color', e.css('backgroundColor'));

      e.css('font-size', 20);

      return false;
});
Профилирования и оптимизация jQuery-кода
Оптимизация .css
• Проводить операции с элементами с display: none, либо до вставки в
  документ;
• заменить несколько css на add/removeClass;
• группировать запросы CSS-свойств в начале функции (когда очередь
  restyle и layout пуста);
• не чередовать запросы и установку CSS у элемента.
Инициализация по требованию
Показания к применению:
•При загрузке страницы одновременно инициализируются множество
одинаковых контролов (модулей, плагинов).

Оптимизация:
•Инициализировать каждый контрол в момент первого обращения к
нему.
Повышение отзывчивости
Симптом:
•В момент выполнения ресурсоемкого кода браузер плохо реагирует
внешние воздействия.

Оптимизация:
•Откладывать трудоемкие итерации через setTimeout.
Общие рекомендации
• Кешируйте все, что может пригодиться;
• отсекайте лишние выборки, инициализацию плагинов и модулей, на
  страницах, на которых они точно не нужны;
• медленный JavaScript — это не единственная и не всегда главная
  причина «тормозов» на сайте;
• не бойтесь пересматривать требования.
robflaherty.github.com/jquery-annotated-source/
Владимир Журавлев
Evil Martians




private.face@gmail.com
github.com/private-face
@private_face

More Related Content

PPT
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
PPT
Профилирование и оптимизация jQuery–кода
PDF
UWDC 2013, Yii2
PDF
UWDC 2013, Как мы используем Yii
PDF
DevConf 2012 - Yii, его разработка и Yii2
PDF
Пластилиновый код: как перестать кодить и начать жить
PDF
Crazy owl yii1=> yii2
PDF
Почему Mojolicious?
Профилирование и оптимизация jQuery–кода (Владимир Журавлёв)
Профилирование и оптимизация jQuery–кода
UWDC 2013, Yii2
UWDC 2013, Как мы используем Yii
DevConf 2012 - Yii, его разработка и Yii2
Пластилиновый код: как перестать кодить и начать жить
Crazy owl yii1=> yii2
Почему Mojolicious?

What's hot (20)

PPT
Easy authcache 2 кеширование для pro родионов игорь
PDF
QA Fest 2019. Андрей Солнцев. Selenide для профи
PPTX
Selenide puzzlers @ devclub.eu
PPTX
Ruby - или зачем мне еще один язык программирования?
PDF
Миша Рудрастых: Введение в HTTP API WordPress
PPTX
Selenium: начало работы
PDF
Basis.js – «под капотом»
PDF
Суперсилы Chrome developer tools
PDF
Алексей Бережной — «jQuery»
PDF
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
PDF
Опыт разработки эффективного SPA
PDF
TARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИС
PDF
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
PPT
Drupal 7 deploy database updates
PPTX
Selenium: приемы работы
PDF
Интуит. Разработка приложений для iOS. Лекция 12. Тестирование, публикация и др.
PDF
Ф'Yii'лософия
PDF
Frontend весна 2014 лекция 1
PPTX
Web осень 2013 лекция 8
PPTX
Максим Щепелин. "Unittesting. Как?"
Easy authcache 2 кеширование для pro родионов игорь
QA Fest 2019. Андрей Солнцев. Selenide для профи
Selenide puzzlers @ devclub.eu
Ruby - или зачем мне еще один язык программирования?
Миша Рудрастых: Введение в HTTP API WordPress
Selenium: начало работы
Basis.js – «под капотом»
Суперсилы Chrome developer tools
Алексей Бережной — «jQuery»
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
Опыт разработки эффективного SPA
TARS: Сделай уровень frontend-рутины 0% — Артём Малко, 2ГИС
Интуит. Разработка приложений для iOS. Лекция 7. Работа с сетью
Drupal 7 deploy database updates
Selenium: приемы работы
Интуит. Разработка приложений для iOS. Лекция 12. Тестирование, публикация и др.
Ф'Yii'лософия
Frontend весна 2014 лекция 1
Web осень 2013 лекция 8
Максим Щепелин. "Unittesting. Как?"
Ad

Viewers also liked (9)

PPTX
Uth Mag Post Event Achievements - Updated
PDF
Vota por isa mayorga
DOC
Kt phat hanh trai phieu
PDF
Overview Of The Bible
PPT
Dominican Young Adults
PDF
Izpostavljenost uporabnikovffs vranac_05
DOC
Ay dawla - copy
PPTX
Domingo de ramos fotos
PPT
Dominics Earth Hour Presentation 2010
Uth Mag Post Event Achievements - Updated
Vota por isa mayorga
Kt phat hanh trai phieu
Overview Of The Bible
Dominican Young Adults
Izpostavljenost uporabnikovffs vranac_05
Ay dawla - copy
Domingo de ramos fotos
Dominics Earth Hour Presentation 2010
Ad

Similar to Профилирования и оптимизация jQuery-кода (20)

PPT
Take more from Jquery
PDF
Behat в PHP с использованием Behat и Mink
PPT
Easy authcache 2 кэширование для pro. Родионов Игорь
PPTX
jQuery. Введение и практика
PPTX
I tmozg js_school
PPT
Rich UI on Dojo Toolkit and Zend Framework
PPT
Мульти-доменность в Django проекте
PPTX
Node.js введение в технологию, КПИ #ITmeetingKPI
PDF
Фундаментальные основы разработки под iOS. Павел Тайкало
PDF
Mobile automation uamobile
PPTX
iOS and Android Mobile Test Automation
PDF
М. Боднарчук Современное функциональное тестирование с Codeception
PDF
Чуть сложнее чем Singleton: аннотации, IOC, АОП
PPTX
Михаил Боднарчук Современное функциональное тестирование с Codeception
PDF
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
PDF
Domain Specific Languages (for business rules)
PPTX
PHP 5.4: Что нового?
PDF
Jsfwdays 2013-2
PDF
Making Scalable JavaScript Application
Take more from Jquery
Behat в PHP с использованием Behat и Mink
Easy authcache 2 кэширование для pro. Родионов Игорь
jQuery. Введение и практика
I tmozg js_school
Rich UI on Dojo Toolkit and Zend Framework
Мульти-доменность в Django проекте
Node.js введение в технологию, КПИ #ITmeetingKPI
Фундаментальные основы разработки под iOS. Павел Тайкало
Mobile automation uamobile
iOS and Android Mobile Test Automation
М. Боднарчук Современное функциональное тестирование с Codeception
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Михаил Боднарчук Современное функциональное тестирование с Codeception
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Domain Specific Languages (for business rules)
PHP 5.4: Что нового?
Jsfwdays 2013-2
Making Scalable JavaScript Application

Профилирования и оптимизация jQuery-кода

Editor's Notes

  • #4: - Простота ведет к тому, что плохой код написать становится еще легче. - обратной стороной кроссбраузерного фасада является то, что далеко не все понимают что происходит за этим фасадом. - а обилие плагинов ведет к тому, что большая часть кода перестает вам принадлежать. И в итоге часто получается, что когда объем j Query кода и количество одновременно подключенных на странице плагинов превышает некий критический порог, сайт начинает жутко тормозить.
  • #5: Страница начинает при загрузке залипать, анимация проигрывается рывками, возникают непонятные задержки между событием и реакцией на это событие. И это проблема.
  • #8: и этим зарабатывает себе пару профессиональных заболеваний. вы их наверняка знаете.
  • #23: Вадим, есть хорошие новости для нас? Как раз для таких случаев существуют жаваскриптовые профайлеры
  • #36: Рекомендую послушать доклад Артемия Ломова «Быстрый удар точно в цель» сегодня в 15.30. Там артемий подробно расскажет как более лучше писать селекторы.
  • #39: Однако увлекаться делегированием тоже не стоит. Потому что при большом количестве делегированных событий вы можете столкнуться с другой проблемой.
  • #49: И раз мы заговорили. Самое время рассказать про то, как происходит рендеринг страницы в браузере. О процессах
  • #53: стрелочка
  • #54: стрелочки
  • #56: разъезжающаяся текстарея, плейер, скрытые элементы