Повышение конверсии через оптимизацию JS

2,937 views

Published on

Слайды с конференции Devconf 2014. Рассказывается, как производительность влияет на конверсию, приводится 8 тонкостей языка, которые нужно знать, чтобы писать самый быстрый код из возможного.

Published in: Technology

Повышение конверсии через оптимизацию JS

  1. 1. РАЗГОНЯЕМ JS Антон Плешивцев aviasales.ru
  2. 2. МЕТАПОИСК
  3. 3. МЕТАПОИСК
  4. 4. МЕТАПОИСК
  5. 5. МЕТАПОИСК
  6. 6. МЕТАПОИСК
  7. 7. ОКНО ДЖОХАРИ Известное продавцу Неизвестное продавцу Известное клиенту Открытое Слепое пятно Неизвестное клиенту Скрытое Неизвестное
  8. 8. ПРОФИЛИРОВАНИЕ • Метод пристального взгляда • Ручное • Инструментальное
  9. 9. СТАТИСТИЧЕСКОЕ
  10. 10. СОБЫТИЙНОЕ
  11. 11. РУЧНОЕ t = +new Date(); code_to_measure(); time = +new Date() - t;
  12. 12. РУЧНОЕ, НО УДОБНОЕ function profile(func){ ! var wrapper = function(){ var start = +new Date(); var result = func.apply(null, arguments); console.log(func.name, +new Date() - start, "ms"); return result; }; ! return wrapper; }
  13. 13. РУЧНОЕ, НО УДОБНОЕ code_to_measure = profile(code_to_measure); ! code_to_measure(); > code_to_measure 112ms
  14. 14. КОНВЕРСИЯ Январь Февраль Март Апрель Май
  15. 15. TIP #1 вызов функций
  16. 16. ! var start = +new Date(); var result = func.apply(null, arguments); console.log(func.name, +new Date() - start, "ms");
  17. 17. switch (args.length) { case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return; case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return; case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return; default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return; }
  18. 18. APPLY & CALL 0 12500000 25000000 37500000 50000000 Apply Call (количество операций в секунду, больше - лучше)
  19. 19. APPLY & CALL & DIRECT 0 17500000 35000000 52500000 70000000 Apply Call Direct (количество операций в секунду, больше - лучше)
  20. 20. TIP #2 быстрые таймауты
  21. 21. setTimeout(function test(){ ! … ! }, 0)
  22. 22. function setZeroTimeout(fn) { timeouts.push(fn); window.postMessage("zero-timeout-message", "*"); } ! window.addEventListener("message", function handleMessage(event) { if (event.source == window && event.data == messageName) { //zero timeout } } , true) http://dbaron.org/log/20100309-faster-timeouts
  23. 23. TIP #3 почему тормозит Underscore
  24. 24. _.map = _.collect = function(obj, iterator, context) { var results = []; ! if (obj == null) return results; ! if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); ! each(obj, function(value, index, list) { results.push(iterator.call(context, value, index, list)); ! }); return results; };
  25. 25. map = function(obj, iterator, context) { if (nativeMap) { map = function(obj, iterator, context){ return obj.map(iterator); } } else { map = function(obj, iterator, context){ var results = []; each(obj, function(value, index, list) { results.push(iterator.call(context, value, index, list)); }); return results; } } return map(obj, iterator, context); };
  26. 26. 0 3,75 7,5 11,25 15 _.map map (время работы в среднем, меньше - лучше)
  27. 27. 0 4 8 12 16 _.map map lodash.map (время работы в среднем, меньше - лучше)
  28. 28. TIP #4 самый быстрый цикл
  29. 29. CLASSIC FOR for (var i = 0; i < arr.length; ++i) { arr[i]; };
  30. 30. CLASSIC FOR WITH LENGTH CACHE for (var i = 0, len = arr.length; i < len; ++i) { arr[i]; };
  31. 31. REVERSE WHILE var i = arr.length; while (i--) { arr[i]; };
  32. 32. WHILE IMITATING FOR var i = 0, len = arr.length; while (i < len) { arr[i]; i++; };
  33. 33. 0 775 1550 2325 3100 classic for for with cache reverse while while imitating for Firefox (количество операций в секунду, больше - лучше)
  34. 34. 160 167,5 175 182,5 190 classic for for with cache reverse while while imitating for Chrome
  35. 35. 0 800 1600 2400 3200 classic for for with cache reverse while while imitating for Firefox Chrome
  36. 36. ПОБЕДИТЕЛЬ var i = 0, len = arr.length; while (i < len) { arr[i]; i++; };
  37. 37. TIP #5 быстрый доступ к ОП
  38. 38. function(){ document.getElementById('sidebar'); document.getElementById('collections'); document.getElementById('logo'); }
  39. 39. function(){ var d = document; d.getElementById('sidebar'); d.getElementById('collections'); d.getElementById('logo'); }
  40. 40. 0 350 700 1050 1400 До После (время на цикле 1М, меньше - лучше)
  41. 41. TIP #6 работа с DOM
  42. 42. JQUERY STRING iframe = $("<iframe src='javascript:false' name='theiframe'>");
  43. 43. JQUERY CHAIN iframe = $(‘<iframe>’).attr({ name: 'theiframe', src: ‘javascript:false' })
  44. 44. NATIVE JS iframe = document.createElement('iframe'); iframe.name = 'theiframe'; iframe.src = 'javascript:false';
  45. 45. FUNCTION iframe = createElement('iframe', { name: 'theiframe', src: ‘javascript:false' });
  46. 46. 0 125000 250000 375000 500000 jQuery string jQuery chain Native js Function (количество операций в секунду, больше - лучше)
  47. 47. TIP #7 самый быстрый фреймворк
  48. 48. 0 750 1500 2250 3000 React Angular Mithril vuejs
  49. 49. TIP #8 self vs bind
  50. 50. var self = this; check(function(){ self.ok(); })
  51. 51. check(function(){ this.ok(); }).bind(this);
  52. 52. 0 7500000 15000000 22500000 30000000 Bind self (количество операций в секунду, больше - лучше)
  53. 53. ПРОФИЛИРУЙТЕ
  54. 54. ЗАМЕРЯЙТЕ
  55. 55. ИЗУЧАЙТЕ
  56. 56. ABOUT АНТОН ПЛЕШИВЦЕВ ! twitter.com/allaud github.com/allaud https://www.facebook.com/ant.pl.3 ! ! ! ! ! ! aviasales.ru

×