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

Preview:

DESCRIPTION

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

Citation preview

РАЗГОНЯЕМ JSАнтон Плешивцев

aviasales.ru

МЕТАПОИСК

МЕТАПОИСК

МЕТАПОИСК

МЕТАПОИСК

МЕТАПОИСК

ОКНО ДЖОХАРИ

Известное продавцу

Неизвестное продавцу

Известное клиенту Открытое Слепое пятно

Неизвестное клиенту Скрытое Неизвестное

ПРОФИЛИРОВАНИЕ

• Метод пристального взгляда

• Ручное

• Инструментальное

СТАТИСТИЧЕСКОЕ

СОБЫТИЙНОЕ

РУЧНОЕ

t = +new Date(); code_to_measure(); time = +new Date() - t;

РУЧНОЕ, НО УДОБНОЕ

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; }

РУЧНОЕ, НО УДОБНОЕ

code_to_measure = profile(code_to_measure); !code_to_measure(); > code_to_measure 112ms

КОНВЕРСИЯ

Январь Февраль Март Апрель Май

TIP #1вызов функций

!var start = +new Date(); var result = func.apply(null, arguments); console.log(func.name, +new Date() - start, "ms");

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; }

APPLY & CALL

0

12500000

25000000

37500000

50000000

Apply Call

(количество операций в секунду, больше - лучше)

APPLY & CALL & DIRECT

0

17500000

35000000

52500000

70000000

Apply Call Direct

(количество операций в секунду, больше - лучше)

TIP #2быстрые таймауты

setTimeout(function test(){ !

… !

}, 0)

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

TIP #3почему тормозит Underscore

_.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; };

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); };

0

3,75

7,5

11,25

15

_.map map

(время работы в среднем, меньше - лучше)

0

4

8

12

16

_.map map lodash.map

(время работы в среднем, меньше - лучше)

TIP #4самый быстрый цикл

CLASSIC FOR

for (var i = 0; i < arr.length; ++i) { arr[i]; };

CLASSIC FOR WITH LENGTH CACHE

for (var i = 0, len = arr.length; i < len; ++i) { arr[i]; };

REVERSE WHILE

var i = arr.length; while (i--) { arr[i]; };

WHILE IMITATING FOR

var i = 0, len = arr.length; while (i < len) { arr[i]; i++; };

0

775

1550

2325

3100

classic for for with cache reverse while while imitating for

Firefox

(количество операций в секунду, больше - лучше)

160

167,5

175

182,5

190

classic for for with cache reverse while while imitating for

Chrome

0

800

1600

2400

3200

classic for for with cache reverse while while imitating for

Firefox Chrome

ПОБЕДИТЕЛЬ

var i = 0, len = arr.length; while (i < len) { arr[i]; i++; };

TIP #5быстрый доступ к ОП

function(){ document.getElementById('sidebar'); document.getElementById('collections'); document.getElementById('logo'); }

function(){ var d = document; d.getElementById('sidebar'); d.getElementById('collections'); d.getElementById('logo'); }

0

350

700

1050

1400

До После

(время на цикле 1М, меньше - лучше)

TIP #6работа с DOM

JQUERY STRING

iframe = $("<iframe src='javascript:false' name='theiframe'>");

JQUERY CHAIN

iframe = $(‘<iframe>’).attr({ name: 'theiframe', src: ‘javascript:false' })

NATIVE JS

iframe = document.createElement('iframe'); iframe.name = 'theiframe'; iframe.src = 'javascript:false';

FUNCTION

iframe = createElement('iframe', { name: 'theiframe', src: ‘javascript:false' });

0

125000

250000

375000

500000

jQuery string jQuery chain Native js Function

(количество операций в секунду, больше - лучше)

TIP #7самый быстрый фреймворк

0

750

1500

2250

3000

React Angular Mithril vuejs

TIP #8self vs bind

var self = this; check(function(){ self.ok(); })

check(function(){ this.ok(); }).bind(this);

0

7500000

15000000

22500000

30000000

Bind self

(количество операций в секунду, больше - лучше)

ПРОФИЛИРУЙТЕ

ЗАМЕРЯЙТЕ

ИЗУЧАЙТЕ

ABOUT

АНТОН ПЛЕШИВЦЕВ !

twitter.com/allaud github.com/allaud

https://www.facebook.com/ant.pl.3 !!!!!!

aviasales.ru

Recommended