SlideShare ist ein Scribd-Unternehmen logo
1 von 115
Downloaden Sie, um offline zu lesen
Как сделать 

ваш JavaScript быстрее
Роман Дворнов
Avito
Руководитель 

фронтенда в Avito
Основной интерес – SPA
Open source:

basis.js, CSSO, 

component-inspector, 

csstree и другие
Вводная
Производительность Frontend'а
• Не всегда проблема (и так быстро)
• Если работает медленно, не всегда это
связано с JavaScript (особенно в браузере)
• Доклад про те ситуации, когда проблема
действительно в JavaScript
4
Как сделать JavaScript
быстрее?
5
Простого ответа нет
• Нужно разбирать каждый случай отдельно
• Пара символов или строк могут изменить
производительность в разы или даже в десятки раз
• На производительность могут влиять внешние факторы
• Тема производительности JavaScript все еще 

не стабильна – все меняется
• Тема огромная, многие аспекты требуют предварительной
подготовки
6
В общем случае, нужно понимать как
работают JavaScript движки, 

что фактически происходит под капотом,
принимать меры там, где это нужно
7
О чем поговорим
• Заблуждения
• Новое в JavaScript
• Внешнее влияние на производительность
• Что можно найти под капотом
8
Мифы и легенды
Разработчики руководствуются
своими представлениями о том,
что быстро и что нет – часто эти
представления не верны
10
4 Javascript Optimisations you
should know
11
leftshift.io/4-javascript-optimisations-you-should-know
Пример вредной статьи
4 апреля 2014
12
Вредный совет #1
hasOwnProperty быстрее switch
switch vs. hasOwnProperty
14
function testSwitch(quality){
    switch (quality) {
        case "Hard Working":
        case "Honest":
        case "Intelligent":
        case "Team player":
            return true;
        default:
            return false;
    }
}
var o = {
    'Hard Working': true,
    'Honest': true,
    'Intelligent': true,
    'Team player': true
};
function testHOP(quality) {
    return o.hasOwnProperty(quality)
}
Нужно перебирать 

все варианты – медленно
Быстрее и гибче
switch vs. hasOwnProperty
15
testSwitch: 4 ms
testHOP: 40 ms
Простой тест показывает обратное
Значит switch быстрее hasOwnProperty?
• Не всегда, в данном случае – да
• В общем случае (в режиме интерпретатора)
обычно медленнее
• Время switch в примере обусловлено его
оптимизацией при компиляции
• В то же время, hasOwnProperty не оптимизируется
16
Намеренно деоптимизируем
17
try/catch не дает функции оптимизироваться (V8)
function testSwitch(quality){
try{}catch(e){}
    switch (quality) {
        case "Hard Working":
        case "Honest":
        case "Intelligent":
        case "Team player":
            return true;
        default:
            return false;
    }
}
var o = {
    'Hard Working': true,
    'Honest': true,
    'Intelligent': true,
    'Team player': true
};
function testHOP(quality) {
try{}catch(e){}
    return o.hasOwnProperty(quality)
}
Результаты
18
testSwitch: 70 ms
testHOP: 42 ms
С оптимизацией
testSwitch: 4 ms
testHOP: 40 ms
Без оптимизации (try/catch)
Выводы
• switch работает быстро, если оптимизируется
• другой код может помешать оптимизации
• могут быть дополнительные ограничения:
например, ранее V8 не оптимизировал switch
если вариантов (case) более 128
19
Вредный совет #2
for..in vs. Object.keys()
for..in vs. Object.keys()
21
for (var key in object) {
    // do something
}
for..in – плохо, потому что перебираются как
собственные ключи так и ключи в цепочке
прототипов
for..in vs. Object.keys()
22
for (var key in object) {
    if (object.hasOwnProperty(key)) {
        // do something
    }
}
лучше проверять, что ключ является собственным,
но это дополнительная проверка
for..in vs. Object.keys()
23
var keys = Object.keys(object);
for (var i = 0; i < keys.length; i++){
    // do something
}
Object.keys() возвращает только собственные
ключи – это лучше и быстрее
for..in vs. Object.keys()
24
forIn: 170 ms
forInHOP: 56 ms
objectKeys: 188 ms
Результаты теста
jsfiddle.net/rdvornov/veeorm09/
Разбираемся
25
for..in действительно перебирает как
собственные ключи так и ключи в цепочке
прототипов – это сложно оптимизировать и
стоит избегать
for (var key in object) {
    // do something
}
Разбираемся
26
дополнительная проверка позволяет оптимизатору
распознать паттерн и сгенерировать код, который
не будет трогать цепочку прототипов
for (var key in object) {
    if (object.hasOwnProperty(key)) {
        // do something
    }
}
Разбираемся
27
да, Object.keys() перебирает только собственные
ключи и это быстро, но в результате создается
временный массив, который нужно итерировать, 

к тому же это создает нагрузку на GC
var keys = Object.keys(object);
for (var i = 0; i < keys.length; i++){
    // do something
}
for..in vs. Object.key()
28
forIn: 170 ms
forInHOP: 56 ms
objectKeys: 188 ms
С оптимизацией
forIn: 202 ms
forInHOP: 232 ms
objectKeys: 244 ms
Без оптимизации
Выводы
• for..in в общем случае немного быстрее
• hasOwnProperty проверка может приводить 

к лучшей оптимизации for..in
• Object.keys() может и отрабатывает быстрее,
но генерирует мусор и не оптимизируется
29
Вредный совет #3
Оптимизация циклов
Оптимизация циклов
31
for (var i = 0; i < array.length; i++) {
    // do something
}
обычный цикл, который чем то не угодил
Оптимизация циклов
32
for (var i = 0, len = array.length; i < len; i++) {
    // do something
}
нужно его ускорить, закешировав длину
массива, но и это не самый быстрый вариант
Оптимизация циклов
33
var i = array.length;
while (i--) {
    //do something
}
while цикл быстрее for
Тест автора статьи
34
var arr = [];
for (var i = 0; i <= 1000000; i++) {
    arr.push(i);
}
console.time("slowLoop");
for (var k = 0, len = arr.length; k < len; k++) {
    // do something
}
console.timeEnd("slowLoop");
console.time("fastLoop");
var j = arr.length;
while (j--) {
    // do something
}
console.timeEnd("fastLoop");
Результаты теста
35
slowLoop: 3.47 ms
fastLoop: 2.52 ms
На самом деле…
• В последних браузерах "slowLoop" обычно
быстрее "fastLoop"
• Временные интервалы малы, в таких случаях
велика погрешность
• Сам по себе тест неверный
36
Разбираемся
37
var arr = [];
for (var i = 0; i <= 1000000; i++) {
    arr.push(i);
}
console.time("slowLoop");
for (var k = 0, len = arr.length; k < len; k++) {
    // do something
}
console.timeEnd("slowLoop");
console.time("fastLoop");
var j = arr.length;
while (j--) {
    // do something
}
console.timeEnd("fastLoop");
Изначально код не
оптимизуется – если код
выполняется лишь раз, нет
смысла оптимизировать
Разбираемся
38
var arr = [];
for (var i = 0; i <= 1000000; i++) {
    arr.push(i);
}
console.time("slowLoop");
for (var k = 0, len = arr.length; k < len; k++) {
    // do something
}
console.timeEnd("slowLoop");
console.time("fastLoop");
var j = arr.length;
while (j--) {
    // do something
}
console.timeEnd("fastLoop");
Тело цикла выполняется
много раз и могло было бы
оптимизироваться, но
здесь оно пустое
Разбираемся
39
var arr = [];
for (var i = 0; i <= 1000000; i++) {
    arr.push(i);
}
console.time("slowLoop");
for (var k = 0, len = arr.length; k < len; k++) {
    // do something
}
console.timeEnd("slowLoop");
console.time("fastLoop");
var j = arr.length;
while (j--) {
    // do something
}
console.timeEnd("fastLoop");
По сути сравнивается
время выполнения этих
инструкций
Выполним тест несколько раз
40
function test(){
    console.time("slowLoop");
    for (var k = 0, len = arr.length; k < len; k++) {
        // do something
    }
    console.timeEnd("slowLoop");
    console.time("fastLoop");
    var j = arr.length;
    while (j--) {
        // do something;
    }
    console.timeEnd("fastLoop");
}
test();
test();
test();
Результаты
41
slowLoop: 3.00 ms
fastLoop: 2.07 ms
slowLoop: 0.85 ms
fastLoop: 1.38 ms
slowLoop: 1.14 ms
fastLoop: 1.57 ms
Результаты
41
slowLoop: 3.00 ms
fastLoop: 2.07 ms
slowLoop: 0.85 ms
fastLoop: 1.38 ms
slowLoop: 1.14 ms
fastLoop: 1.57 ms
Первое исполнение без оптимизации
Последующие с оптимизацией
Промежуточные выводы
• Код оптимизируется по мере разогрева
• Простые функции оптимизируются на
втором-третьем вызове
• Оптимизированный код может поменять
картину
42
Так как же быстрее всего?
43
Поменяем подход к тестированию
44
function test(x){
  loop {
      x++;
  }
  return x;
}
console.time('test');
for (var i = 0, res = 0; i < 100; i++) {
    res += test(i);
}
console.timeEnd('test');
• каждую функцию выполняем
несколько раз – даем
возможность оптимизациям
• добавляем одинаковую
полезную нагрузку –
увеличиваем время
выполнения уменьшаем
влияние погрешности
• избегаем dead code
elimination
Результаты
45
for: 155ms
forCache: 156ms
while: 183ms
С оптимизацией
for: 494ms
forCache: 460ms
while: 605ms
Без оптимизации
Выводы
• while быстрее for – миф из прошлого
• для современных движков обычно нет
необходимости кешировать значения в циклах
• на скорость цикла больше влияет
оптимизация чем форма записи
46
Подводим итоги
Выводы
• Гипотезы нужно подтверждать тестами
• Часто код работает не так, как мы думаем
• Не стоит жить мифами, движки
эволюционируют – нужно освежать свои знания
• Микробенчмарки – зло, если создаются без
понимания работы движков
48
Советы
• Не стоит доверять всему, что пишут в интернетах
или говорят в докладах, перепроверяйте
• Наиболее точная информация в публикациях
разработчиков браузеров, движков и независимых
авторов, объясняющих почему именно так
• Смотрите на дату публикации, даже верные
утверждения могут устареть
49
Новое не всегда хорошо
JavaScript развивается –
появляются новые удобные
конструкции, но не стоит
забывать о производительности
51
Поддержка со стороны движка
не означает, что это работает
быстро
52
Правда жизни
• Часто новые возможности реализуют по принципу
"чтобы работало" – без учета производительности
• Новые конструкции могут не оптимизироваться и
мешать оптимизации сопряженного кода
• Некоторые возможности из ES5/ES6/etc в
принципе не могут быть оптимизированы

и работать быстро
53
var vs. let/const
Сегодня стало "модно" везде
заменять var на let или const
55
Однако, в V8 (Chrome/node.js)
let/const медленнее var в 2 раза,
в остальных движках время
одинаковое
56
jsperf.com/let-vs-var-performance/50
– Вячеслав Егоров
“... [const] это все-таки неизменяемая привязка
переменной к значению ...
С другой стороны виртуальная машина может и
должна бы использовать это самое свойство
неизменяемости ...
V8 не использует, к сожалению.”
57
habrahabr.ru/company/jugru/blog/301040/#comment_9622474
Promise
Два года назад, я решил узнать
насколько мой полифил для
Promise медленней нативной
реализации…
59
github.com/lahmatiy/es6-promise-polyfill
Тест №1
60
var a = []; // чтобы инстансы не разрушались/собирались GC
var t = performance.now();
for (var i = 0; i < 10000; i++)
  a.push(new Promise(function(){}));
  
console.log(performance.now() - t);
Тест №2
61
var a = []; // чтобы инстансы не разрушались/собирались GC
var t = performance.now();
for (var i = 0; i < 10000; i++)
  a.push(new Promise(function(r, rj){ a.push(r, rj) }));
  
console.log(performance.now() - t);
Promise – 2 года назад
62
gist.github.com/lahmatiy/d4d6316418fe349537dc
Test 1 Test 2
Native Polyfill Native Polyfill
Chrome 35 105 15 154 18
Firefox 30 90 17 113 25
IE11 – 5 – 6
время в миллисекундах
Promise – сегодня
63
Test 1 Test 2
Native Polyfill Native Polyfill
Chrome 54 12.5 5.8 13.7 8
Firefox 49 101 31 119.2 43.1
Edge 14 12.7 25.7 22.2 40.2
Safari 10 3.7 1.8 4.3 2.3
время в миллисекундах
Полифил Promise (не самый
быстрый) по прежнему быстрее
нативных реализаций 

почти во всех движках/браузерах
64
Это афектит все Promise-based
API и новые фичи 

вроде async/await
65
Я попытался еще ускорить
полифил Promise, например,
используя Function#bind вместо
замыканий…
66
closure vs. Function#bind
По идее Function#bind должен
быть дешевле (быстрее)
68
Результаты – 2 года назад
69
gist.github.com/lahmatiy/3d97ee23f3d89941970f
Closure Function#bind
Chrome 35 14 28
Firefox 30 10.3 17.1
IE11 9.3 2.9
время в миллисекундах
Результаты – сегодня
70
Closure Function#bind
Chrome 54 2.5 0.8
Firefox 49 3.8 5.7
Edge 14 5.1 4.2
Safari 10 1.0 4.0
время в миллисекундах
Метод Function#bind все еще
медленней (не оптимизирован)
замыканий в ряде движков
71
Транспиляция
Транспиляция (например, ES6→ES5)
уменьшает возможность влиять на код 

и его производительность
73
Транспиляция может оказывать как
положительный эффект, например,
оптимизация кода на основе
статического анализа
74
Возможно и негативное влияние,
когда сгенерированный код не может
быть оптимизирован – в таких случаях
стоит переписать код на ES5/ES3
75
Подводим итоги
Выводы
• Новое не всегда работает быстро
• Нужно время, чтобы в движки добавили
новые оптимизации и что-то заработало
быстро
77
Советы
• Все новое в JavaScript стоит проверять – работает
ли быстро, оптимизируется ли
• Стоит читать блоги/release notes разработчиков
движков и браузеров, в них пишут о добавлении
новых оптимизаций
• Критические к производительности места стоит
писать на ES3/ES5
78
Беда может прийти откуда не ждешь
Даже если сам JavaScript
работает быстро, внешние
факторы могут значительно
влиять на его производительность
80
Внешние API
JavaScript код взаимодествует с
внешними системами и API –
таймеры, DOM, файловая
система, сеть и т.д.
82
Это не часть JavaScript, однако
API часто синхронное и время
его вызова прибавляется ко
времени выполнения JavaScript
83
Пример: DOM
84
function doSomething(el, viewport) {
    el.style.width = viewport.offsetWidth + 'px';
    el.style.height = viewport.offsetHeight + 'px';
}
С точки зрения JavaScript, здесь все просто
и нечего оптимизировать
Пример: DOM
85
function doSomething(el, viewport) {
    el.style.width = viewport.offsetWidth + 'px';
    el.style.height = viewport.offsetHeight + 'px';
}
Но для второго чтения потребуется сделать
пересчет layout'а (дорогая операция), так как
до этого был изменен DOM
Пример: DOM
86
function doSomething(el, viewport) {
    var width = viewport.offsetWidth;
    var height = viewport.offsetHeight;
    el.style.width = width + 'px';
    el.style.height = height + 'px';
}
В этом случае сначала делается чтение, потом
запись – код не тригирует пересчет layout'а
Стоит помнить
• Время выполнения внешних API добавляется
к JavaScript и останавливает его выполнение
• Не все, что доступно в JavaScript является
его частью
• Внешние API могут приводить к побочным
явлениям (side effect) затратным по времени
87
Память
Говоря о производительности
JavaScript, часто забывают 

о важном компоненте – памяти
89
Выделение памяти
90
var array = [];
for (var i = 0; i < 1000; i++) {
    array.push(i);
}
Плохо – может приводить к релокации
фрагментов памяти (массивы хранятся
одним фрагментом)
Выделение памяти
91
var array = new Array(1000);
for (var i = 0; i < 1000; i++) {
    array[i] = i;
}
Лучше – может помочь избежать релокацию,
так как сразу выделится нужно кол-во памяти
Так же можно использовать структуры
данных, позволяющие избегать релокации,
например, TypedArray или списки
92
Подробнее в докладе:
Парсим CSS: performance tips & tricks
GC может все испортить
93
94
Пример
Влияние GC
95
> node --trace-gc test.js
...
[91494:0x102001000] 374 ms: Scavenge 35.3 (56.9) -> 35.0 (57.9) MB, 30.0 / 0.0 ms [allocation failure]
[91494:0x102001000] 443 ms: Scavenge 38.2 (59.9) -> 38.1 (74.9) MB, 46.2 / 0.0 ms [allocation failure]
===== run #1 152 ms
===== run #2 63 ms
===== run #3 44 ms
...
===== run #7 58
[91494:0x102001000] 896 ms: Scavenge 135.2 (159.9) -> 135.0 (160.9) MB, 31.5 / 0.0 ms [allocation fail
[91494:0x102001000] 965 ms: Scavenge 140.0 (163.9) -> 140.0 (178.9) MB, 59.2 / 0.0 ms [allocation fail
===== run #8 131 ms
===== run #9 43 ms
===== run #10 46 ms
Эволюция GC
• молодая и старая память
• инкрементальная сборка мусора
• параллельная сборка мусора
96
Простые советы
• Используем меньше памяти – быстрее
• Генерируем меньше мусора – быстрее
• Нужно понимать как происходит выделение
памяти и сборка мусора (GC)
97
Лезем под капот
Чтобы работать над ускорением
JavaScript, важно понимать как
устроены и работают JavaScript
движки
99
С чем стоит разобраться
• hidden class
• monomorphic, polymorphic, megamorphic
• inline cache
• function inlining
• dead code elimination
• tenuring
• ...
100
Хорошее начало – блог и
доклады Вячеслава Егорова
mrale.ph/blog/
101
Блоги браузеров – ценный
источник информации
102
Помимо этого
• Как работает железо (процессор, память –
регистры, адресация)
• Иметь преставление что такое машинный код
• Структуры данных (стек, etc)
• Как представляются структуры данных в
низкоуровневых языках (массивы, строки)
103
Самый верный способ узнать,
что на самом деле выполняет
движок – посмотреть внутреннее
представление
104
105
node --trace-hydrogen 
--trace-phase=Z 
--trace-deopt 
--code-comments 
--hydrogen-track-positions 
--redirect-code-traces 
--redirect-code-traces-to=code.asm 
--trace_hydrogen_file=code.cfg 
--print-opt-code 
your-script.js
Получаем данные о работе кода
106
mrale.ph/irhydra/2/
code.asm
code.cfg
Заключение
Без понимания того, как
устроены JavaScript движки
крайне сложно писать
производительный код
109
Тема объемна – ее не постичь
за короткое время, потому
нужно понемногу в ней копаться
110
ВремясжатияCSS(600Kb)
500 ms
1 000 ms
1 500 ms
2 000 ms
2 500 ms
3 000 ms
3 500 ms
4 000 ms
4 500 ms
5 000 ms
5 500 ms
6 000 ms
Версия CSSO
1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 2.0
1 050 ms
clean-css
Оно того стоит: изменение скорости CSSO
csso
500 ms
cssnano
23 250 ms
112
CSSTree: 7 ms
Mensch: 31 ms
CSSOM: 36 ms
PostCSS: 38 ms
Rework: 81 ms
PostCSS Full: 100 ms
Gonzales: 175 ms
Stylecow: 176 ms
Gonzales PE: 214 ms
ParserLib: 414 ms
Оно того стоит: CSSTree
github.com/postcss/benchmark
Разбор bootstrap.css v3.3.7 (146Kb)
Парсер CSSTree появился в результате
многочисленного рефакторинга Gonzales
Подробнее в докладе:
Парсим CSS: performance tips & tricks
Ищите объяснения, почему что-то
работает быстро или медленно – 

тогда вы сами сможете ответить
на вопрос как сделать ваш
JavaScript быстрее
113
Роман Дворнов
@rdvornov
github.com/lahmatiy
rdvornov@gmail.com
Спасибо!

Weitere ähnliche Inhalte

Was ist angesagt?

Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...corehard_by
 
Developing highload servers with Java
Developing highload servers with JavaDeveloping highload servers with Java
Developing highload servers with JavaAndrei Pangin
 
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...Ontico
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаSergey Platonov
 
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)Ontico
 
Java tricks for high-load server programming
Java tricks for high-load server programmingJava tricks for high-load server programming
Java tricks for high-load server programmingAndrei Pangin
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиvictor-yastrebov
 
Caching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaCaching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaAndrei Pangin
 
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
 Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo) Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)Ontico
 
Распределенные системы в Одноклассниках
Распределенные системы в ОдноклассникахРаспределенные системы в Одноклассниках
Распределенные системы в Одноклассникахodnoklassniki.ru
 
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Ontico
 
Незаурядная Java как инструмент разработки высоконагруженного сервера
Незаурядная Java как инструмент разработки высоконагруженного сервераНезаурядная Java как инструмент разработки высоконагруженного сервера
Незаурядная Java как инструмент разработки высоконагруженного сервераodnoklassniki.ru
 
Выжимаем из сервера максимум (Андрей Паньгин)
Выжимаем из сервера максимум (Андрей Паньгин)Выжимаем из сервера максимум (Андрей Паньгин)
Выжимаем из сервера максимум (Андрей Паньгин)Ontico
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actualYevgen Levik
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один goBadoo Development
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеPython Meetup
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAlex Tumanoff
 
"Fault tolerant workflow orchestration on PHP", Anton Tsitou
"Fault tolerant workflow orchestration on PHP", Anton Tsitou"Fault tolerant workflow orchestration on PHP", Anton Tsitou
"Fault tolerant workflow orchestration on PHP", Anton TsitouFwdays
 
My talk at Highload++ 2015
My talk at Highload++ 2015My talk at Highload++ 2015
My talk at Highload++ 2015Alex Chistyakov
 

Was ist angesagt? (20)

Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
Модульность и управляемая многопоточность встраиваемых С++ приложений - трудн...
 
Developing highload servers with Java
Developing highload servers with JavaDeveloping highload servers with Java
Developing highload servers with Java
 
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
Основы индексирования и расширенные возможности EXPLAIN в MySQL / Василий Лук...
 
Павел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладкаПавел Довгалюк, Обратная отладка
Павел Довгалюк, Обратная отладка
 
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
Производительность WebGL-приложений / Дмитренко Кирилл (Яндекс)
 
Java tricks for high-load server programming
Java tricks for high-load server programmingJava tricks for high-load server programming
Java tricks for high-load server programming
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 
Caching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaCaching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in Java
 
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
 Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo) Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
Отладка производительности приложения на Erlang / Максим Лапшин (Erlyvideo)
 
Распределенные системы в Одноклассниках
Распределенные системы в ОдноклассникахРаспределенные системы в Одноклассниках
Распределенные системы в Одноклассниках
 
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)
 
Незаурядная Java как инструмент разработки высоконагруженного сервера
Незаурядная Java как инструмент разработки высоконагруженного сервераНезаурядная Java как инструмент разработки высоконагруженного сервера
Незаурядная Java как инструмент разработки высоконагруженного сервера
 
Выжимаем из сервера максимум (Андрей Паньгин)
Выжимаем из сервера максимум (Андрей Паньгин)Выжимаем из сервера максимум (Андрей Паньгин)
Выжимаем из сервера максимум (Андрей Паньгин)
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actual
 
Семь тысяч Rps, один go
Семь тысяч Rps, один goСемь тысяч Rps, один go
Семь тысяч Rps, один go
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
Async clinic by by Sergey Teplyakov
Async clinic by by Sergey TeplyakovAsync clinic by by Sergey Teplyakov
Async clinic by by Sergey Teplyakov
 
"Fault tolerant workflow orchestration on PHP", Anton Tsitou
"Fault tolerant workflow orchestration on PHP", Anton Tsitou"Fault tolerant workflow orchestration on PHP", Anton Tsitou
"Fault tolerant workflow orchestration on PHP", Anton Tsitou
 
My talk at Highload++ 2015
My talk at Highload++ 2015My talk at Highload++ 2015
My talk at Highload++ 2015
 

Andere mochten auch

Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими рукамиRoman Dvornov
 
DOM-шаблонизаторы – не только "быстро"
DOM-шаблонизаторы – не только "быстро"DOM-шаблонизаторы – не только "быстро"
DOM-шаблонизаторы – не только "быстро"Roman Dvornov
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныRoman Dvornov
 
CSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksCSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksRoman Dvornov
 
CSSO – compress CSS (english version)
CSSO – compress CSS (english version)CSSO – compress CSS (english version)
CSSO – compress CSS (english version)Roman Dvornov
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!Roman Dvornov
 
Быстро о быстром
Быстро о быстромБыстро о быстром
Быстро о быстромRoman Dvornov
 
CSSO — минимизируем CSS
 CSSO — минимизируем CSS CSSO — минимизируем CSS
CSSO — минимизируем CSSRoman Dvornov
 
Basis.js – «под капотом»
Basis.js – «под капотом»Basis.js – «под капотом»
Basis.js – «под капотом»Roman Dvornov
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструментыRoman Dvornov
 
Не бойся, это всего лишь данные... просто их много
Не бойся, это всего лишь данные... просто их многоНе бойся, это всего лишь данные... просто их много
Не бойся, это всего лишь данные... просто их многоRoman Dvornov
 
Карточный домик
Карточный домикКарточный домик
Карточный домикRoman Dvornov
 
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)AvitoTech
 
"Погружение в Robolectric" Дмитрий Костырев (Avito)
"Погружение в Robolectric"  Дмитрий Костырев (Avito)"Погружение в Robolectric"  Дмитрий Костырев (Avito)
"Погружение в Robolectric" Дмитрий Костырев (Avito)AvitoTech
 
"Sphinx 3.0 в реальной жизни" Андрей Смирнов (Avito)
"Sphinx 3.0 в реальной жизни" Андрей Смирнов (Avito)"Sphinx 3.0 в реальной жизни" Андрей Смирнов (Avito)
"Sphinx 3.0 в реальной жизни" Андрей Смирнов (Avito)AvitoTech
 
"RT индексы в поиске Avito" Вячеслав Крюков (Avito)
"RT индексы в поиске Avito" Вячеслав Крюков (Avito)"RT индексы в поиске Avito" Вячеслав Крюков (Avito)
"RT индексы в поиске Avito" Вячеслав Крюков (Avito)AvitoTech
 
Жизнь в изоляции
Жизнь в изоляцииЖизнь в изоляции
Жизнь в изоляцииRoman Dvornov
 
Golang в avito
Golang в avitoGolang в avito
Golang в avitoAvitoTech
 
PostgreSQL worst practices, version FOSDEM PGDay 2017 by Ilya Kosmodemiansky
PostgreSQL worst practices, version FOSDEM PGDay 2017 by Ilya KosmodemianskyPostgreSQL worst practices, version FOSDEM PGDay 2017 by Ilya Kosmodemiansky
PostgreSQL worst practices, version FOSDEM PGDay 2017 by Ilya KosmodemianskyPostgreSQL-Consulting
 

Andere mochten auch (20)

Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими руками
 
Парсим CSS
Парсим CSSПарсим CSS
Парсим CSS
 
DOM-шаблонизаторы – не только "быстро"
DOM-шаблонизаторы – не только "быстро"DOM-шаблонизаторы – не только "быстро"
DOM-шаблонизаторы – не только "быстро"
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важны
 
CSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksCSS parsing: performance tips & tricks
CSS parsing: performance tips & tricks
 
CSSO – compress CSS (english version)
CSSO – compress CSS (english version)CSSO – compress CSS (english version)
CSSO – compress CSS (english version)
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!
 
Быстро о быстром
Быстро о быстромБыстро о быстром
Быстро о быстром
 
CSSO — минимизируем CSS
 CSSO — минимизируем CSS CSSO — минимизируем CSS
CSSO — минимизируем CSS
 
Basis.js – «под капотом»
Basis.js – «под капотом»Basis.js – «под капотом»
Basis.js – «под капотом»
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструменты
 
Не бойся, это всего лишь данные... просто их много
Не бойся, это всего лишь данные... просто их многоНе бойся, это всего лишь данные... просто их много
Не бойся, это всего лишь данные... просто их много
 
Карточный домик
Карточный домикКарточный домик
Карточный домик
 
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
"Basis.js - Production Ready SPA Framework" Сергей Мелюков (Avito)
 
"Погружение в Robolectric" Дмитрий Костырев (Avito)
"Погружение в Robolectric"  Дмитрий Костырев (Avito)"Погружение в Robolectric"  Дмитрий Костырев (Avito)
"Погружение в Robolectric" Дмитрий Костырев (Avito)
 
"Sphinx 3.0 в реальной жизни" Андрей Смирнов (Avito)
"Sphinx 3.0 в реальной жизни" Андрей Смирнов (Avito)"Sphinx 3.0 в реальной жизни" Андрей Смирнов (Avito)
"Sphinx 3.0 в реальной жизни" Андрей Смирнов (Avito)
 
"RT индексы в поиске Avito" Вячеслав Крюков (Avito)
"RT индексы в поиске Avito" Вячеслав Крюков (Avito)"RT индексы в поиске Avito" Вячеслав Крюков (Avito)
"RT индексы в поиске Avito" Вячеслав Крюков (Avito)
 
Жизнь в изоляции
Жизнь в изоляцииЖизнь в изоляции
Жизнь в изоляции
 
Golang в avito
Golang в avitoGolang в avito
Golang в avito
 
PostgreSQL worst practices, version FOSDEM PGDay 2017 by Ilya Kosmodemiansky
PostgreSQL worst practices, version FOSDEM PGDay 2017 by Ilya KosmodemianskyPostgreSQL worst practices, version FOSDEM PGDay 2017 by Ilya Kosmodemiansky
PostgreSQL worst practices, version FOSDEM PGDay 2017 by Ilya Kosmodemiansky
 

Ähnlich wie Как сделать ваш JavaScript быстрее

Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.Igor Shkulipa
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
PostgreSQL performance recipes
PostgreSQL performance recipesPostgreSQL performance recipes
PostgreSQL performance recipesAlexey Ermakov
 
Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting   Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting Yandex
 
Статический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибокСтатический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибокAndrey Karpov
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишковcorehard_by
 
Экономически эффективный процесс тестирования (Codefest 2015)
Экономически эффективный процесс тестирования (Codefest 2015)Экономически эффективный процесс тестирования (Codefest 2015)
Экономически эффективный процесс тестирования (Codefest 2015)Andrei Solntsev
 
Экономически эффективный процесс тестирования
Экономически эффективный процесс тестированияЭкономически эффективный процесс тестирования
Экономически эффективный процесс тестированияCodeFest
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.Roman Brovko
 
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...Ontico
 
OpenSource SQL Databases Enter Millions Queries per Second Era
OpenSource SQL Databases Enter Millions Queries per Second EraOpenSource SQL Databases Enter Millions Queries per Second Era
OpenSource SQL Databases Enter Millions Queries per Second EraSveta Smirnova
 
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013Unigine Corp.
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Platonov Sergey
 
20111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture320111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture3Computer Science Club
 
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестовЮлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестовMskDotNet Community
 
Борзунов Александр, Cpmoptimize
Борзунов Александр, CpmoptimizeБорзунов Александр, Cpmoptimize
Борзунов Александр, CpmoptimizeDarya Zubova
 

Ähnlich wie Как сделать ваш JavaScript быстрее (20)

PowerShell
PowerShellPowerShell
PowerShell
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.C++ STL & Qt. Занятие 10.
C++ STL & Qt. Занятие 10.
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
PostgreSQL performance recipes
PostgreSQL performance recipesPostgreSQL performance recipes
PostgreSQL performance recipes
 
10M tests per day
10M tests per day10M tests per day
10M tests per day
 
Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting   Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting
 
Статический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибокСтатический анализ кода: борьба с удорожанием ошибок
Статический анализ кода: борьба с удорожанием ошибок
 
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья ШишковC++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
C++ CoreHard Autumn 2018. Заглядываем под капот «Поясов по C++» - Илья Шишков
 
Экономически эффективный процесс тестирования (Codefest 2015)
Экономически эффективный процесс тестирования (Codefest 2015)Экономически эффективный процесс тестирования (Codefest 2015)
Экономически эффективный процесс тестирования (Codefest 2015)
 
Экономически эффективный процесс тестирования
Экономически эффективный процесс тестированияЭкономически эффективный процесс тестирования
Экономически эффективный процесс тестирования
 
Лекция 11. Тестирование.
Лекция 11. Тестирование.Лекция 11. Тестирование.
Лекция 11. Тестирование.
 
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
 
OpenSource SQL Databases Enter Millions Queries per Second Era
OpenSource SQL Databases Enter Millions Queries per Second EraOpenSource SQL Databases Enter Millions Queries per Second Era
OpenSource SQL Databases Enter Millions Queries per Second Era
 
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
Низкоуровневые оптимизации. Андрей Аксенов. Unigine Open Air 2013
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
20111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture320111002 information retrieval raskovalov_lecture3
20111002 information retrieval raskovalov_lecture3
 
Python и Cython
Python и CythonPython и Cython
Python и Cython
 
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестовЮлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
 
Борзунов Александр, Cpmoptimize
Борзунов Александр, CpmoptimizeБорзунов Александр, Cpmoptimize
Борзунов Александр, Cpmoptimize
 

Mehr von Roman Dvornov

Unit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерUnit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерRoman Dvornov
 
Масштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаМасштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаRoman Dvornov
 
CSS глазами машин
CSS глазами машинCSS глазами машин
CSS глазами машинRoman Dvornov
 
My Open Source (Sept 2017)
My Open Source (Sept 2017)My Open Source (Sept 2017)
My Open Source (Sept 2017)Roman Dvornov
 
Rempl – крутая платформа для крутых инструментов
Rempl – крутая платформа для крутых инструментовRempl – крутая платформа для крутых инструментов
Rempl – крутая платформа для крутых инструментовRoman Dvornov
 
CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)Roman Dvornov
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Как построить DOM
Как построить DOMКак построить DOM
Как построить DOMRoman Dvornov
 
Компонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноКомпонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноRoman Dvornov
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Roman Dvornov
 
basis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкbasis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкRoman Dvornov
 

Mehr von Roman Dvornov (12)

Unit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерUnit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьер
 
Масштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаМасштабируемая архитектура фронтенда
Масштабируемая архитектура фронтенда
 
CSS глазами машин
CSS глазами машинCSS глазами машин
CSS глазами машин
 
My Open Source (Sept 2017)
My Open Source (Sept 2017)My Open Source (Sept 2017)
My Open Source (Sept 2017)
 
Rempl – крутая платформа для крутых инструментов
Rempl – крутая платформа для крутых инструментовRempl – крутая платформа для крутых инструментов
Rempl – крутая платформа для крутых инструментов
 
CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)
 
Component Inspector
Component InspectorComponent Inspector
Component Inspector
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Как построить DOM
Как построить DOMКак построить DOM
Как построить DOM
 
Компонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноКомпонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективно
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
 
basis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкbasis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворк
 

Как сделать ваш JavaScript быстрее

  • 1. Как сделать 
 ваш JavaScript быстрее Роман Дворнов Avito
  • 2. Руководитель 
 фронтенда в Avito Основной интерес – SPA Open source:
 basis.js, CSSO, 
 component-inspector, 
 csstree и другие
  • 4. Производительность Frontend'а • Не всегда проблема (и так быстро) • Если работает медленно, не всегда это связано с JavaScript (особенно в браузере) • Доклад про те ситуации, когда проблема действительно в JavaScript 4
  • 6. Простого ответа нет • Нужно разбирать каждый случай отдельно • Пара символов или строк могут изменить производительность в разы или даже в десятки раз • На производительность могут влиять внешние факторы • Тема производительности JavaScript все еще 
 не стабильна – все меняется • Тема огромная, многие аспекты требуют предварительной подготовки 6
  • 7. В общем случае, нужно понимать как работают JavaScript движки, 
 что фактически происходит под капотом, принимать меры там, где это нужно 7
  • 8. О чем поговорим • Заблуждения • Новое в JavaScript • Внешнее влияние на производительность • Что можно найти под капотом 8
  • 10. Разработчики руководствуются своими представлениями о том, что быстро и что нет – часто эти представления не верны 10
  • 11. 4 Javascript Optimisations you should know 11 leftshift.io/4-javascript-optimisations-you-should-know Пример вредной статьи 4 апреля 2014
  • 12. 12
  • 14. switch vs. hasOwnProperty 14 function testSwitch(quality){     switch (quality) {         case "Hard Working":         case "Honest":         case "Intelligent":         case "Team player":             return true;         default:             return false;     } } var o = {     'Hard Working': true,     'Honest': true,     'Intelligent': true,     'Team player': true }; function testHOP(quality) {     return o.hasOwnProperty(quality) } Нужно перебирать 
 все варианты – медленно Быстрее и гибче
  • 15. switch vs. hasOwnProperty 15 testSwitch: 4 ms testHOP: 40 ms Простой тест показывает обратное
  • 16. Значит switch быстрее hasOwnProperty? • Не всегда, в данном случае – да • В общем случае (в режиме интерпретатора) обычно медленнее • Время switch в примере обусловлено его оптимизацией при компиляции • В то же время, hasOwnProperty не оптимизируется 16
  • 17. Намеренно деоптимизируем 17 try/catch не дает функции оптимизироваться (V8) function testSwitch(quality){ try{}catch(e){}     switch (quality) {         case "Hard Working":         case "Honest":         case "Intelligent":         case "Team player":             return true;         default:             return false;     } } var o = {     'Hard Working': true,     'Honest': true,     'Intelligent': true,     'Team player': true }; function testHOP(quality) { try{}catch(e){}     return o.hasOwnProperty(quality) }
  • 18. Результаты 18 testSwitch: 70 ms testHOP: 42 ms С оптимизацией testSwitch: 4 ms testHOP: 40 ms Без оптимизации (try/catch)
  • 19. Выводы • switch работает быстро, если оптимизируется • другой код может помешать оптимизации • могут быть дополнительные ограничения: например, ранее V8 не оптимизировал switch если вариантов (case) более 128 19
  • 21. for..in vs. Object.keys() 21 for (var key in object) {     // do something } for..in – плохо, потому что перебираются как собственные ключи так и ключи в цепочке прототипов
  • 22. for..in vs. Object.keys() 22 for (var key in object) {     if (object.hasOwnProperty(key)) {         // do something     } } лучше проверять, что ключ является собственным, но это дополнительная проверка
  • 23. for..in vs. Object.keys() 23 var keys = Object.keys(object); for (var i = 0; i < keys.length; i++){     // do something } Object.keys() возвращает только собственные ключи – это лучше и быстрее
  • 24. for..in vs. Object.keys() 24 forIn: 170 ms forInHOP: 56 ms objectKeys: 188 ms Результаты теста jsfiddle.net/rdvornov/veeorm09/
  • 25. Разбираемся 25 for..in действительно перебирает как собственные ключи так и ключи в цепочке прототипов – это сложно оптимизировать и стоит избегать for (var key in object) {     // do something }
  • 26. Разбираемся 26 дополнительная проверка позволяет оптимизатору распознать паттерн и сгенерировать код, который не будет трогать цепочку прототипов for (var key in object) {     if (object.hasOwnProperty(key)) {         // do something     } }
  • 27. Разбираемся 27 да, Object.keys() перебирает только собственные ключи и это быстро, но в результате создается временный массив, который нужно итерировать, 
 к тому же это создает нагрузку на GC var keys = Object.keys(object); for (var i = 0; i < keys.length; i++){     // do something }
  • 28. for..in vs. Object.key() 28 forIn: 170 ms forInHOP: 56 ms objectKeys: 188 ms С оптимизацией forIn: 202 ms forInHOP: 232 ms objectKeys: 244 ms Без оптимизации
  • 29. Выводы • for..in в общем случае немного быстрее • hasOwnProperty проверка может приводить 
 к лучшей оптимизации for..in • Object.keys() может и отрабатывает быстрее, но генерирует мусор и не оптимизируется 29
  • 31. Оптимизация циклов 31 for (var i = 0; i < array.length; i++) {     // do something } обычный цикл, который чем то не угодил
  • 32. Оптимизация циклов 32 for (var i = 0, len = array.length; i < len; i++) {     // do something } нужно его ускорить, закешировав длину массива, но и это не самый быстрый вариант
  • 33. Оптимизация циклов 33 var i = array.length; while (i--) {     //do something } while цикл быстрее for
  • 34. Тест автора статьи 34 var arr = []; for (var i = 0; i <= 1000000; i++) {     arr.push(i); } console.time("slowLoop"); for (var k = 0, len = arr.length; k < len; k++) {     // do something } console.timeEnd("slowLoop"); console.time("fastLoop"); var j = arr.length; while (j--) {     // do something } console.timeEnd("fastLoop");
  • 36. На самом деле… • В последних браузерах "slowLoop" обычно быстрее "fastLoop" • Временные интервалы малы, в таких случаях велика погрешность • Сам по себе тест неверный 36
  • 37. Разбираемся 37 var arr = []; for (var i = 0; i <= 1000000; i++) {     arr.push(i); } console.time("slowLoop"); for (var k = 0, len = arr.length; k < len; k++) {     // do something } console.timeEnd("slowLoop"); console.time("fastLoop"); var j = arr.length; while (j--) {     // do something } console.timeEnd("fastLoop"); Изначально код не оптимизуется – если код выполняется лишь раз, нет смысла оптимизировать
  • 38. Разбираемся 38 var arr = []; for (var i = 0; i <= 1000000; i++) {     arr.push(i); } console.time("slowLoop"); for (var k = 0, len = arr.length; k < len; k++) {     // do something } console.timeEnd("slowLoop"); console.time("fastLoop"); var j = arr.length; while (j--) {     // do something } console.timeEnd("fastLoop"); Тело цикла выполняется много раз и могло было бы оптимизироваться, но здесь оно пустое
  • 39. Разбираемся 39 var arr = []; for (var i = 0; i <= 1000000; i++) {     arr.push(i); } console.time("slowLoop"); for (var k = 0, len = arr.length; k < len; k++) {     // do something } console.timeEnd("slowLoop"); console.time("fastLoop"); var j = arr.length; while (j--) {     // do something } console.timeEnd("fastLoop"); По сути сравнивается время выполнения этих инструкций
  • 40. Выполним тест несколько раз 40 function test(){     console.time("slowLoop");     for (var k = 0, len = arr.length; k < len; k++) {         // do something     }     console.timeEnd("slowLoop");     console.time("fastLoop");     var j = arr.length;     while (j--) {         // do something;     }     console.timeEnd("fastLoop"); } test(); test(); test();
  • 41. Результаты 41 slowLoop: 3.00 ms fastLoop: 2.07 ms slowLoop: 0.85 ms fastLoop: 1.38 ms slowLoop: 1.14 ms fastLoop: 1.57 ms
  • 42. Результаты 41 slowLoop: 3.00 ms fastLoop: 2.07 ms slowLoop: 0.85 ms fastLoop: 1.38 ms slowLoop: 1.14 ms fastLoop: 1.57 ms Первое исполнение без оптимизации Последующие с оптимизацией
  • 43. Промежуточные выводы • Код оптимизируется по мере разогрева • Простые функции оптимизируются на втором-третьем вызове • Оптимизированный код может поменять картину 42
  • 44. Так как же быстрее всего? 43
  • 45. Поменяем подход к тестированию 44 function test(x){   loop {       x++;   }   return x; } console.time('test'); for (var i = 0, res = 0; i < 100; i++) {     res += test(i); } console.timeEnd('test'); • каждую функцию выполняем несколько раз – даем возможность оптимизациям • добавляем одинаковую полезную нагрузку – увеличиваем время выполнения уменьшаем влияние погрешности • избегаем dead code elimination
  • 46. Результаты 45 for: 155ms forCache: 156ms while: 183ms С оптимизацией for: 494ms forCache: 460ms while: 605ms Без оптимизации
  • 47. Выводы • while быстрее for – миф из прошлого • для современных движков обычно нет необходимости кешировать значения в циклах • на скорость цикла больше влияет оптимизация чем форма записи 46
  • 49. Выводы • Гипотезы нужно подтверждать тестами • Часто код работает не так, как мы думаем • Не стоит жить мифами, движки эволюционируют – нужно освежать свои знания • Микробенчмарки – зло, если создаются без понимания работы движков 48
  • 50. Советы • Не стоит доверять всему, что пишут в интернетах или говорят в докладах, перепроверяйте • Наиболее точная информация в публикациях разработчиков браузеров, движков и независимых авторов, объясняющих почему именно так • Смотрите на дату публикации, даже верные утверждения могут устареть 49
  • 52. JavaScript развивается – появляются новые удобные конструкции, но не стоит забывать о производительности 51
  • 53. Поддержка со стороны движка не означает, что это работает быстро 52
  • 54. Правда жизни • Часто новые возможности реализуют по принципу "чтобы работало" – без учета производительности • Новые конструкции могут не оптимизироваться и мешать оптимизации сопряженного кода • Некоторые возможности из ES5/ES6/etc в принципе не могут быть оптимизированы
 и работать быстро 53
  • 56. Сегодня стало "модно" везде заменять var на let или const 55
  • 57. Однако, в V8 (Chrome/node.js) let/const медленнее var в 2 раза, в остальных движках время одинаковое 56 jsperf.com/let-vs-var-performance/50
  • 58. – Вячеслав Егоров “... [const] это все-таки неизменяемая привязка переменной к значению ... С другой стороны виртуальная машина может и должна бы использовать это самое свойство неизменяемости ... V8 не использует, к сожалению.” 57 habrahabr.ru/company/jugru/blog/301040/#comment_9622474
  • 60. Два года назад, я решил узнать насколько мой полифил для Promise медленней нативной реализации… 59 github.com/lahmatiy/es6-promise-polyfill
  • 61. Тест №1 60 var a = []; // чтобы инстансы не разрушались/собирались GC var t = performance.now(); for (var i = 0; i < 10000; i++)   a.push(new Promise(function(){}));    console.log(performance.now() - t);
  • 62. Тест №2 61 var a = []; // чтобы инстансы не разрушались/собирались GC var t = performance.now(); for (var i = 0; i < 10000; i++)   a.push(new Promise(function(r, rj){ a.push(r, rj) }));    console.log(performance.now() - t);
  • 63. Promise – 2 года назад 62 gist.github.com/lahmatiy/d4d6316418fe349537dc Test 1 Test 2 Native Polyfill Native Polyfill Chrome 35 105 15 154 18 Firefox 30 90 17 113 25 IE11 – 5 – 6 время в миллисекундах
  • 64. Promise – сегодня 63 Test 1 Test 2 Native Polyfill Native Polyfill Chrome 54 12.5 5.8 13.7 8 Firefox 49 101 31 119.2 43.1 Edge 14 12.7 25.7 22.2 40.2 Safari 10 3.7 1.8 4.3 2.3 время в миллисекундах
  • 65. Полифил Promise (не самый быстрый) по прежнему быстрее нативных реализаций 
 почти во всех движках/браузерах 64
  • 66. Это афектит все Promise-based API и новые фичи 
 вроде async/await 65
  • 67. Я попытался еще ускорить полифил Promise, например, используя Function#bind вместо замыканий… 66
  • 69. По идее Function#bind должен быть дешевле (быстрее) 68
  • 70. Результаты – 2 года назад 69 gist.github.com/lahmatiy/3d97ee23f3d89941970f Closure Function#bind Chrome 35 14 28 Firefox 30 10.3 17.1 IE11 9.3 2.9 время в миллисекундах
  • 71. Результаты – сегодня 70 Closure Function#bind Chrome 54 2.5 0.8 Firefox 49 3.8 5.7 Edge 14 5.1 4.2 Safari 10 1.0 4.0 время в миллисекундах
  • 72. Метод Function#bind все еще медленней (не оптимизирован) замыканий в ряде движков 71
  • 74. Транспиляция (например, ES6→ES5) уменьшает возможность влиять на код 
 и его производительность 73
  • 75. Транспиляция может оказывать как положительный эффект, например, оптимизация кода на основе статического анализа 74
  • 76. Возможно и негативное влияние, когда сгенерированный код не может быть оптимизирован – в таких случаях стоит переписать код на ES5/ES3 75
  • 78. Выводы • Новое не всегда работает быстро • Нужно время, чтобы в движки добавили новые оптимизации и что-то заработало быстро 77
  • 79. Советы • Все новое в JavaScript стоит проверять – работает ли быстро, оптимизируется ли • Стоит читать блоги/release notes разработчиков движков и браузеров, в них пишут о добавлении новых оптимизаций • Критические к производительности места стоит писать на ES3/ES5 78
  • 80. Беда может прийти откуда не ждешь
  • 81. Даже если сам JavaScript работает быстро, внешние факторы могут значительно влиять на его производительность 80
  • 83. JavaScript код взаимодествует с внешними системами и API – таймеры, DOM, файловая система, сеть и т.д. 82
  • 84. Это не часть JavaScript, однако API часто синхронное и время его вызова прибавляется ко времени выполнения JavaScript 83
  • 85. Пример: DOM 84 function doSomething(el, viewport) {     el.style.width = viewport.offsetWidth + 'px';     el.style.height = viewport.offsetHeight + 'px'; } С точки зрения JavaScript, здесь все просто и нечего оптимизировать
  • 86. Пример: DOM 85 function doSomething(el, viewport) {     el.style.width = viewport.offsetWidth + 'px';     el.style.height = viewport.offsetHeight + 'px'; } Но для второго чтения потребуется сделать пересчет layout'а (дорогая операция), так как до этого был изменен DOM
  • 87. Пример: DOM 86 function doSomething(el, viewport) {     var width = viewport.offsetWidth;     var height = viewport.offsetHeight;     el.style.width = width + 'px';     el.style.height = height + 'px'; } В этом случае сначала делается чтение, потом запись – код не тригирует пересчет layout'а
  • 88. Стоит помнить • Время выполнения внешних API добавляется к JavaScript и останавливает его выполнение • Не все, что доступно в JavaScript является его частью • Внешние API могут приводить к побочным явлениям (side effect) затратным по времени 87
  • 90. Говоря о производительности JavaScript, часто забывают 
 о важном компоненте – памяти 89
  • 91. Выделение памяти 90 var array = []; for (var i = 0; i < 1000; i++) {     array.push(i); } Плохо – может приводить к релокации фрагментов памяти (массивы хранятся одним фрагментом)
  • 92. Выделение памяти 91 var array = new Array(1000); for (var i = 0; i < 1000; i++) {     array[i] = i; } Лучше – может помочь избежать релокацию, так как сразу выделится нужно кол-во памяти
  • 93. Так же можно использовать структуры данных, позволяющие избегать релокации, например, TypedArray или списки 92 Подробнее в докладе: Парсим CSS: performance tips & tricks
  • 94. GC может все испортить 93
  • 96. Влияние GC 95 > node --trace-gc test.js ... [91494:0x102001000] 374 ms: Scavenge 35.3 (56.9) -> 35.0 (57.9) MB, 30.0 / 0.0 ms [allocation failure] [91494:0x102001000] 443 ms: Scavenge 38.2 (59.9) -> 38.1 (74.9) MB, 46.2 / 0.0 ms [allocation failure] ===== run #1 152 ms ===== run #2 63 ms ===== run #3 44 ms ... ===== run #7 58 [91494:0x102001000] 896 ms: Scavenge 135.2 (159.9) -> 135.0 (160.9) MB, 31.5 / 0.0 ms [allocation fail [91494:0x102001000] 965 ms: Scavenge 140.0 (163.9) -> 140.0 (178.9) MB, 59.2 / 0.0 ms [allocation fail ===== run #8 131 ms ===== run #9 43 ms ===== run #10 46 ms
  • 97. Эволюция GC • молодая и старая память • инкрементальная сборка мусора • параллельная сборка мусора 96
  • 98. Простые советы • Используем меньше памяти – быстрее • Генерируем меньше мусора – быстрее • Нужно понимать как происходит выделение памяти и сборка мусора (GC) 97
  • 100. Чтобы работать над ускорением JavaScript, важно понимать как устроены и работают JavaScript движки 99
  • 101. С чем стоит разобраться • hidden class • monomorphic, polymorphic, megamorphic • inline cache • function inlining • dead code elimination • tenuring • ... 100
  • 102. Хорошее начало – блог и доклады Вячеслава Егорова mrale.ph/blog/ 101
  • 103. Блоги браузеров – ценный источник информации 102
  • 104. Помимо этого • Как работает железо (процессор, память – регистры, адресация) • Иметь преставление что такое машинный код • Структуры данных (стек, etc) • Как представляются структуры данных в низкоуровневых языках (массивы, строки) 103
  • 105. Самый верный способ узнать, что на самом деле выполняет движок – посмотреть внутреннее представление 104
  • 106. 105 node --trace-hydrogen --trace-phase=Z --trace-deopt --code-comments --hydrogen-track-positions --redirect-code-traces --redirect-code-traces-to=code.asm --trace_hydrogen_file=code.cfg --print-opt-code your-script.js Получаем данные о работе кода
  • 108.
  • 110. Без понимания того, как устроены JavaScript движки крайне сложно писать производительный код 109
  • 111. Тема объемна – ее не постичь за короткое время, потому нужно понемногу в ней копаться 110
  • 112. ВремясжатияCSS(600Kb) 500 ms 1 000 ms 1 500 ms 2 000 ms 2 500 ms 3 000 ms 3 500 ms 4 000 ms 4 500 ms 5 000 ms 5 500 ms 6 000 ms Версия CSSO 1.4.0 1.5.0 1.6.0 1.7.0 1.8.0 2.0 1 050 ms clean-css Оно того стоит: изменение скорости CSSO csso 500 ms cssnano 23 250 ms
  • 113. 112 CSSTree: 7 ms Mensch: 31 ms CSSOM: 36 ms PostCSS: 38 ms Rework: 81 ms PostCSS Full: 100 ms Gonzales: 175 ms Stylecow: 176 ms Gonzales PE: 214 ms ParserLib: 414 ms Оно того стоит: CSSTree github.com/postcss/benchmark Разбор bootstrap.css v3.3.7 (146Kb) Парсер CSSTree появился в результате многочисленного рефакторинга Gonzales Подробнее в докладе: Парсим CSS: performance tips & tricks
  • 114. Ищите объяснения, почему что-то работает быстро или медленно – 
 тогда вы сами сможете ответить на вопрос как сделать ваш JavaScript быстрее 113