SlideShare uma empresa Scribd logo
1 de 100
Baixar para ler offline
Как построить DOM

Роман Дворнов
Ostrovok.ru
Киев, Октябрь 2013
Немного о себе
• Работаю в Ostrovok.ru
• Ранее руководил
веб-разработкой в
ПС Единый кошелек

• Автор и мейтейнер
фреймворка basis.js

2
Зачем нам DOM?

3
Веб-приложения
• Компонентный подход, переиспользование
• Разделение отвественности
• Много разных данных
• Ленивое построение
• Точечные обновления
• Динамика, динамика, динамика...
4
Компонентный подход
=
декомпозиция

5
Обычный подход
list
item
item
item
item
item

6
Компонентный подход
list

item
item
item
item
item
7
Обычный подход
window
form
field
field
button panel
button
8

button
Компонентный подход
window

form

field
field

button panel
button

button
9
Обычный подход
function renderList(data){
var html = '';
html = html + '<ul class="mylist' +
(cls ? ' ' + cls : '') + '">';
for (var i = 0; i < items.length; i++)
html = html + '<li class="item ' +
(items[i].selected ? ' selected' : '') + '>' +
items[i].title +
'</li>';
html = html + '</ul>';
return html;
};
...
element.innerHTML = renderList({ .. });
10
Обычный подход
function renderList(data){
var html = '';
html = html + '<ul class="mylist' +
(cls ? ' ' + cls : '') + '">';
for (var i = 0; i < items.length; i++)
html = html + '<li class="item ' +
(items[i].selected ? ' selected' : '') + '>' +
items[i].title +
'</li>';
html = html + '</ul>';
return html;
};
...
element.innerHTML = renderList({ .. });
11
DOM спасет мир
динамический веб

12
Первый подход
или жизнь без шаблонов

13
Hardcore – DOM
var Item = basis.ui.Node.subclass({
init: function(config){
this.element = basis.dom.create('li.item', // создание DOM
basis.dom.create('span.caption',
this.title = basis.dom.createText(config.title)
)
);
},
setTitle: function(title){
this.title.nodeValue = title; // точечное обновление
},
destroy: function(){
...
this.element = null;
// обнуление ссылок
this.title = null;
}
});
14
Hardcore – события
var Item = basis.ui.Node.subclass({
init: function(config){
...
// подписка на события
basis.dom.event.on(this.element, 'click', onclick, this);
},
...
onclick: function(event){ // подписанные методы получают event
this.selected ? this.unselect() : this.select();
},
...
destroy: function(){
...
// отписываемся
basis.dom.event.off(this.element, 'click', onclick, this);
}
});
15
Как быстро?

16
Speed tree – «подопытный кролик»

17
Результаты
IE11

Firefox26 Chrome30 Opera12 iPhone4S

100 узлов, ms

45

15

8

10

50

2000 узлов, ms

1014

309

183

174

981

18
Доля работы с DOM
Speed tree – 2000 узлов
IE11

Firefox26 Chrome30 Opera12 iPhone4S

общее время, ms

1014

309

183

174

981

создание DOM, ms

785

246

151

134

807

создание DOM, %

77,4

79,6

82,5

77,0

82,3

Более 75% тратится на создание DOM
19
Минусы подхода
1. Медленое создание DOM фрагмента
2. Сложно менять "описание"
3. Нужно самостоятельно привязывать и
удалять обработчики событий
4. Много кода по обновлению DOM
5. Не наглядно
6. Легко получить утечки памяти
20
Решаем проблему

Медленное создание
DOM

21
Отказ от удобств
this.element = basis.dom.create('li.item');

this.element = document.createElement('li');
this.element.className = 'item';

22
Отказ от удобств
Speed tree – 2000 узлов
IE11

Firefox26 Chrome30 Opera12 iPhone4S

выигрыш, ms

463

171

110

92

540

выигрыш, %

59,0 %

69,5 %

72,8 %

68,7 %

66,9 %

было

785

246

151

134

807

23
Привязка событий
• Добавляем обработчики на элемент
корневого компонента

• Жертвуем возможностью определять
слушаемые события в коде дочерних
компонент

• Один обработчик для каждого типа
события вместо N

24
Привязка событий
Speed tree – 2000 узлов
IE11

Firefox26 Chrome30 Opera12 iPhone4S

выигрыш, ms

115

37

23

13

118

выигрыш, %

14,6 %

15,0 %

15,2 %

9,7 %

14,6 %

было

785

246

151

134

807

25
cloneNode(true)
var Leaf = basis.ui.Node.subclass({
proto: basis.dom.create('li.item', // эталон
basis.dom.create('span.caption',
basis.dom.createText('no title')
)
),
init: function(cfg){
...
// получаем клон
this.element = this.proto.cloneNode(true);
this.title = this.element.firstChild.firstChild;
this.title.nodeValue = cfg.title || 'no title';
}
});

26
Минимизируем
операции с DOM
• Любая операция с DOM чего-то стоит
• Даже присвоение того же значения, что
уже есть у свойства, часто равносильно
присвоению нового значения

• Даже операции чтения, то есть

обращение к свойствам firstChild,
lastChild, nextSibling и т.д.
27
Меньше операций с DOM
Speed tree – 2000 узлов
IE11

Firefox26 Chrome30 Opera12 iPhone4S

выигрыш, ms

49

18

5

15

9

выигрыш, %

6,2 %

7,3 %

3,3 %

11,2 %

1,1 %

было

785

246

151

134

807

28
После всех оптимизаций
Speed tree – 2000 узлов
IE11

Firefox26 Chrome30 Opera12 iPhone4S

было

785

246

151

134

807

стало

158

20

13

14

140

выигрыш, ms

627

226

138

120

667

выигрыш, %

79,9 %

91,9 %

91,4 %

89,6 %

82,7 %

29
Минус один
1. Медленое создание DOM фрагмента
2. Сложно менять "описание"
3. Нужно самостоятельно привязывать и
удалять обработчики событий
4. Много кода по обновлению DOM
5. Не наглядно
6. Легко получить утечки памяти
30
Решаем проблему

Сложность описания

31
И тут появляются
шаблоны

32
basis.html.Template
var Leaf = basis.ui.Node.subclass({
template: new basis.html.Template(
'<li{element} class="item">{title}</li>'
),
init: function(){
...
// этот вызов создаст DOM фрагмент и вернет карту
this.tmpl = this.template.createInstance();
this.tmpl.title.nodeValue = this.title;
}
});

33
template.createInstance(..)
Создает DOM фрагмент
и возвращает карту ссылок
{

<div{element}>

element: <div>,
title: #text,
content: <ul>

<h2>{title}</h2>
<ul{content}/>
</div>

}

34
Парсинг описания
• Без использования innerHTML
• Комбинация RegExp и конечного
автомата

• Позволяет использовать собственные
конструкции и теги

• Делается только раз
35
Минус два
1. Медленое создание DOM фрагмента
2. Сложно менять "описание"
3. Нужно самостоятельно привязывать и
удалять обработчики событий
4. Много кода по обновлению DOM
5. Не наглядно
6. Легко получить утечки памяти
36
Решаем проблему

Привязка событий

37
В шаблоне
<li{element} class="item" event-click="select">
{title}
</li>

38
В коде
var Leaf = basis.ui.Node.subclass({
...
action: {
select: function(event){
action – дополняется
this.select();
при наследовании
},
...
}
});

39
Как это работает

40
Событийная модель
Document
<HTML>
<BODY>
<DIV>
<BUTTON>
41
Событийная модель
Document
<HTML>
<BODY>

Capture phase

<DIV>

нельзя прервать

<BUTTON>
41
Событийная модель
Document

Bubbling phase

<HTML>

можно прервать

<BODY>

Capture phase

<DIV>

нельзя прервать

<BUTTON>
41
Добавляем обработчик
Document

Bubbling phase

<HTML>

можно прервать

<BODY>

Capture phase

<DIV>

нельзя прервать

<BUTTON>
42
Добавляем обработчик
Document
<HTML>
<BODY>
document.addEventListener(
'eventName', find, true);

<DIV>
<BUTTON>

42
Document
<HTML>
<BODY>
document.addEventListener(
'eventName', find, true);

<DIV>
<BUTTON>

43
Document
<HTML>
<BODY>
<DIV>
<BUTTON>
43

find(event)
1. Ищем ближайший от target элемент
с атрибутом event-{eventName}
2. От него ближайший элемент
с basisTemplateId
Document

3. По ID определяем шаблон и владельца

<HTML>

event

<BODY>
<DIV>
<BUTTON>
43

find(event)
IE8 и старые браузеры
Описание шаблона
<div event-click="action">
{title}
</div>

Шаблонизатор добавляет атрибут в эталонный DOM фрагмент,
но только для браузеров без addEventListener
<div event-click="action"
onclick="basisTemplateHandler('click', event)">
{title}
</div>
// basisTemplateHandler вызывает find
44
Привязка событий
• Один глобальный обработчик на каждое
уникальное событие

• Привязки и отвязки обработчиков как
таковых нет

• Можно добавить одно и тоже действие
на несколько узлов

• Изменение шаблона ничего не ломает
• Нет места для утечек памяти
45
Минус три
1. Медленое создание DOM фрагмента
2. Сложно менять "описание"
3. Нужно самостоятельно привязывать и
удалять обработчики событий
4. Много кода по обновлению DOM
5. Не наглядно
6. Легко получить утечки памяти
46
Решаем проблему

Обновление DOM

47
В шаблоне
<li class="item {selected} {disabled}">
<span title="title is {title}">
{title} ({count})
</span>
</li>

48
В коде
var Leaf = basis.ui.Node.subclass({
title: 'no title',
binding: {
title: function(leaf){
binding – дополняется
return leaf.title;
при наследовании
}
},
setTitle: function(newTitle){
this.title = newTitle;
this.updateBind('title'); // когда надо обновить
}
});

49
Если есть события
var Leaf = basis.ui.Node.subclass({
binding: {
disabled: {
events: ['disable', 'enable'],
getter: function(leaf){
return leaf.isDisabled();
}
}
}
});

50
Проблемы решены
1. Медленое создание DOM фрагмента
2. Сложно менять "описание"
3. Нужно самостоятельно привязывать и
удалять обработчики событий
4. Много кода по обновлению DOM
5. Не наглядно
6. Легко получить утечки памяти
51
Компоненты независимы
от описания шаблона
большая часть операций с DOM
автоматизирована и осуществляется
шаблоном
52
Разделение логики и
представления
JavaScript

Document
DOM
операции

binding

Шаблон

Объект
event
listeners

action

53

(DOM fragment)
DOM vs. Template
Speed tree 2000 узлов
IE11

Firefox26 Chrome30 Opera12 iPhone4S

DOM

785

246

151

134

807

DOM
+ оптимизации

158

20

13

14

140

basis.js templates

230

65

55

58

337

54
DOM vs. innerHTML

55
Причем тут innerHTML?
• Является простым и наиболее

популярным трансформатором
HTML → DOM

• Его использует метод jQuery.html
56
innerHTML baseline
 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

 
 
 
 
 
 
 
 

this.element = document.createElement('li');
this.element.className = 'tree-node';
this.element.innerHTML =
  '<div class="title">' +
    '<span class="caption">' +
      this.data.title +
    '</span>' +
  '</div>';

57
DOM vs. innerHTML
Speed tree – 2000 узлов
IE11

Firefox24 Chrome30 Opera12 iPhone4S

DOM
+ оптимизации

158

20

13

14

140

basis.js templates

230

65

55

58

337

innerHTML

217

42

44

37

272

58
DOM vs. innerHTML
Speed tree – 2000 узлов
IE11

Firefox24 Chrome30 Opera12 iPhone4S

DOM
+ оптимизации

158

20

13

14

140

basis.js templates

230

65

55

58

337

innerHTML

217

42

44

37

272

Но здесь нет пост-процессинга
59
DOM vs. innerHTML
Speed tree – 2000 узлов
IE11

Firefox24 Chrome30 Opera12 iPhone4S

DOM
+ оптимизации

158

20

13

14

140

basis.js templates

230

65

55

58

337

innerHTML

217

42

44

37

272

А тут есть
60
Пост-процессинг
• Добавление классов и другие изменения
DOM фрагмента

• Навешивание обработчиков событий
• Получение ссылок на элементы
61
Пример из TodoMVC
на backbone.js
app.TodoView = Backbone.View.extend({
...
render: function () {
this.$el.html(this.template(this.model.toJSON()));
this.$el.toggleClass('completed',
this.model.get('completed'));
this.toggleVisible();
this.$input = this.$('.edit');
return this;
},
...
});

tinyurl.com/nkpcyd6
62
Делаем так же
this.$el = $('<li>').attr({ class: 'tree-node' });
this.element = this.$el[0];
this.$el.html('...html...');
this.childNodesElement = $el.find('.content')[0];
this.$el.toggleClass('selected', this.selected);
this.$el.toggleClass('disabled', this.disabled);
this.$el.on('click', '.caption', this.select.bind(this));

63
DOM vs. innerHTML
Speed tree – 2000 узлов
IE11

Firefox24 Chrome30 Opera12 iPhone4S

DOM
+ оптимизации

158

20

13

14

140

basis.js templates

230

65

55

58

337

innerHTML

217

42

44

37

272

backbone style

499

296

306

208

1138

64
— У вас никогда не будет
2000 узлов?

65
«640КБ должно быть
достаточно для каждого»
Билл Гейтс, 1981-й год

66
67
Цифры не включают
reflow и repaint

68
Не включают время
создания компонент

69
В бою
• Более сложные шаблоны, композиция
• Дополнительная логика
• Обработка данных
• Создание нескольких view в один момент
• И многое другое...
70
В бою то же время будет
для гораздо меньшего
количества узлов

71
Выводы

72
innerHTML достаточно
быстрый, но медленный
пост-процессинг

73
Построение DOM
применяя API и
оптимизации
быстрее innerHTML

74
Шаблоны basis.js –
удобный способ создавать
и обслуживать DOM
фрагменты

75
И эти шаблоны умеют
много чего еще
Подключение стилей, live update, темы,
локализация, интроспекция,
инструменты, ...
76
Заключение

77
Изучайте и используйте
DOM

78
Сравнивайте

79
Экспериментируйте

80
Ищите решения

81
И получится что-то
крутое :)

82
Но это еще не все...

83
basis-templates.js
basis.js template & l10n modules
as standalone library

84
basis-templates.js
63.2 KB min
23.7 KB min + gzip

85
basisjs.com/templates

github.com/basisjs/templates
86
basis-templates.js
библиотека ориентирована на
встраивание в системы и фреймворки,
в виде модулей или плагинов
87
bbt.js
backbone basis-templates.js plugin

88
backbone.js – 510 ms
backbone.js + bbt.js – 202 ms

89
TodoMVC
100 todo

1000 todo

AngularJS

125 ms

1491 ms

Backbone.js

53 ms

510 ms

Knockout

39 ms

489 ms

vanilla

23 ms

1882 ms

jQuery

20 ms

184 ms

Backbone.js + bbt.js

18 ms

202 ms

basis.js

8 ms

95 ms

90
Переделаны только
шаблон и код TodoView
для использования
basis-templates.js

91
В планах
• Уменьшить объем
• Улучшить API
• Обеспечить поддержку live update, тем и
других возможностей шаблонов basis.js

• Tasks для grunt (live update и сборка)
• Больше примеров и документации
92
basis-templates.js

Пробуйте, используйте,
принимайте участие!
github.com/basisjs/templates
93
basis-templates.js

Сделаем веб быстрее!

github.com/basisjs/templates
94
Вопросы?

Минск, Октябрь 2013

Роман Дворнов
@rdvornov
rdvornov@gmail.com

basis.js
basisjs.com
github.com/basisjs

Mais conteúdo relacionado

Mais procurados

JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.Igor Shkulipa
 
CSS-в-JS, HTML-в-JS, ВСЁ-в-JS. Все гораздо проще, когда всё вокруг JavaScript
CSS-в-JS, HTML-в-JS, ВСЁ-в-JS. Все гораздо проще, когда всё вокруг JavaScriptCSS-в-JS, HTML-в-JS, ВСЁ-в-JS. Все гораздо проще, когда всё вокруг JavaScript
CSS-в-JS, HTML-в-JS, ВСЁ-в-JS. Все гораздо проще, когда всё вокруг JavaScriptAlexey Ivanov
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.Igor Shkulipa
 
ДАМП 2015 Екатеринбург
ДАМП 2015 ЕкатеринбургДАМП 2015 Екатеринбург
ДАМП 2015 ЕкатеринбургAlexey Ivanov
 
Внутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackВнутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackAlexey Ivanov
 
Basis.js — почему я не бросил разрабатывать свой фреймворк / Роман Дворнов (О...
Basis.js — почему я не бросил разрабатывать свой фреймворк / Роман Дворнов (О...Basis.js — почему я не бросил разрабатывать свой фреймворк / Роман Дворнов (О...
Basis.js — почему я не бросил разрабатывать свой фреймворк / Роман Дворнов (О...Ontico
 
Алексей Андросов "Тотальная заморозка = быстрая загрузка"
Алексей Андросов "Тотальная заморозка = быстрая загрузка"Алексей Андросов "Тотальная заморозка = быстрая загрузка"
Алексей Андросов "Тотальная заморозка = быстрая загрузка"Yandex
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныRoman Dvornov
 
Knockoutjs на примере 2ГИС-Онлайн
Knockoutjs на примере 2ГИС-ОнлайнKnockoutjs на примере 2ГИС-Онлайн
Knockoutjs на примере 2ГИС-Онлайн2ГИС Технологии
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструментыRoman Dvornov
 
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Ontico
 
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов2ГИС Технологии
 
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)Ontico
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.Igor Shkulipa
 
МРТ для данных, Frontend Conf 2016
МРТ для данных, Frontend Conf 2016МРТ для данных, Frontend Conf 2016
МРТ для данных, Frontend Conf 2016Anastasia Goryacheva
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Roman Dvornov
 
Изоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесьИзоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесьCodeFest
 
Опыт разработки эффективного SPA
Опыт разработки эффективного SPAОпыт разработки эффективного SPA
Опыт разработки эффективного SPAEugene Abrosimov
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node jsAlex Tumanoff
 

Mais procurados (20)

JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.
 
CSS-в-JS, HTML-в-JS, ВСЁ-в-JS. Все гораздо проще, когда всё вокруг JavaScript
CSS-в-JS, HTML-в-JS, ВСЁ-в-JS. Все гораздо проще, когда всё вокруг JavaScriptCSS-в-JS, HTML-в-JS, ВСЁ-в-JS. Все гораздо проще, когда всё вокруг JavaScript
CSS-в-JS, HTML-в-JS, ВСЁ-в-JS. Все гораздо проще, когда всё вокруг JavaScript
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.
 
ДАМП 2015 Екатеринбург
ДАМП 2015 ЕкатеринбургДАМП 2015 Екатеринбург
ДАМП 2015 Екатеринбург
 
Внутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackВнутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpack
 
Basis.js — почему я не бросил разрабатывать свой фреймворк / Роман Дворнов (О...
Basis.js — почему я не бросил разрабатывать свой фреймворк / Роман Дворнов (О...Basis.js — почему я не бросил разрабатывать свой фреймворк / Роман Дворнов (О...
Basis.js — почему я не бросил разрабатывать свой фреймворк / Роман Дворнов (О...
 
Алексей Андросов "Тотальная заморозка = быстрая загрузка"
Алексей Андросов "Тотальная заморозка = быстрая загрузка"Алексей Андросов "Тотальная заморозка = быстрая загрузка"
Алексей Андросов "Тотальная заморозка = быстрая загрузка"
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важны
 
Knockoutjs на примере 2ГИС-Онлайн
Knockoutjs на примере 2ГИС-ОнлайнKnockoutjs на примере 2ГИС-Онлайн
Knockoutjs на примере 2ГИС-Онлайн
 
SPA инструменты
SPA инструментыSPA инструменты
SPA инструменты
 
Js fuckworks
Js fuckworksJs fuckworks
Js fuckworks
 
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
 
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
«Организация Frontend-разработки на крупном проекте» — Дмитрий Кузнецов
 
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.
 
МРТ для данных, Frontend Conf 2016
МРТ для данных, Frontend Conf 2016МРТ для данных, Frontend Conf 2016
МРТ для данных, Frontend Conf 2016
 
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
Basis.js - почему я не бросил разрабатывать свой фреймворк (extended)
 
Изоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесьИзоморфный JavaScript — будущее уже здесь
Изоморфный JavaScript — будущее уже здесь
 
Опыт разработки эффективного SPA
Опыт разработки эффективного SPAОпыт разработки эффективного SPA
Опыт разработки эффективного SPA
 
Windows Azure and node js
Windows Azure and node jsWindows Azure and node js
Windows Azure and node js
 

Destaque

UX-дизайнер, ты ли это. Навыки проектировщика в стилизации интерфейсов / Илья...
UX-дизайнер, ты ли это. Навыки проектировщика в стилизации интерфейсов / Илья...UX-дизайнер, ты ли это. Навыки проектировщика в стилизации интерфейсов / Илья...
UX-дизайнер, ты ли это. Навыки проектировщика в стилизации интерфейсов / Илья...Ontico
 
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...Ontico
 
What Makes Great Infographics
What Makes Great InfographicsWhat Makes Great Infographics
What Makes Great InfographicsSlideShare
 
Masters of SlideShare
Masters of SlideShareMasters of SlideShare
Masters of SlideShareKapost
 
STOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
STOP! VIEW THIS! 10-Step Checklist When Uploading to SlideshareSTOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
STOP! VIEW THIS! 10-Step Checklist When Uploading to SlideshareEmpowered Presentations
 
10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation OptimizationOneupweb
 
How To Get More From SlideShare - Super-Simple Tips For Content Marketing
How To Get More From SlideShare - Super-Simple Tips For Content MarketingHow To Get More From SlideShare - Super-Simple Tips For Content Marketing
How To Get More From SlideShare - Super-Simple Tips For Content MarketingContent Marketing Institute
 
2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShare2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShareSlideShare
 
What to Upload to SlideShare
What to Upload to SlideShareWhat to Upload to SlideShare
What to Upload to SlideShareSlideShare
 
How to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & TricksHow to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & TricksSlideShare
 
Getting Started With SlideShare
Getting Started With SlideShareGetting Started With SlideShare
Getting Started With SlideShareSlideShare
 

Destaque (12)

UX-дизайнер, ты ли это. Навыки проектировщика в стилизации интерфейсов / Илья...
UX-дизайнер, ты ли это. Навыки проектировщика в стилизации интерфейсов / Илья...UX-дизайнер, ты ли это. Навыки проектировщика в стилизации интерфейсов / Илья...
UX-дизайнер, ты ли это. Навыки проектировщика в стилизации интерфейсов / Илья...
 
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
 
What Makes Great Infographics
What Makes Great InfographicsWhat Makes Great Infographics
What Makes Great Infographics
 
Masters of SlideShare
Masters of SlideShareMasters of SlideShare
Masters of SlideShare
 
STOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
STOP! VIEW THIS! 10-Step Checklist When Uploading to SlideshareSTOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
STOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
 
You Suck At PowerPoint!
You Suck At PowerPoint!You Suck At PowerPoint!
You Suck At PowerPoint!
 
10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization
 
How To Get More From SlideShare - Super-Simple Tips For Content Marketing
How To Get More From SlideShare - Super-Simple Tips For Content MarketingHow To Get More From SlideShare - Super-Simple Tips For Content Marketing
How To Get More From SlideShare - Super-Simple Tips For Content Marketing
 
2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShare2015 Upload Campaigns Calendar - SlideShare
2015 Upload Campaigns Calendar - SlideShare
 
What to Upload to SlideShare
What to Upload to SlideShareWhat to Upload to SlideShare
What to Upload to SlideShare
 
How to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & TricksHow to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & Tricks
 
Getting Started With SlideShare
Getting Started With SlideShareGetting Started With SlideShare
Getting Started With SlideShare
 

Semelhante a Как построить DOM

Михаил Давыдов — JavaScript: События
Михаил Давыдов — JavaScript: СобытияМихаил Давыдов — JavaScript: События
Михаил Давыдов — JavaScript: СобытияYandex
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов ИгорьPVasili
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Yulia Tsisyk
 
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»MskDotNet Community
 
"Опыт разработки универсальной библиотеки визуальных компонентов в HeadHunter...
"Опыт разработки универсальной библиотеки визуальных компонентов в HeadHunter..."Опыт разработки универсальной библиотеки визуальных компонентов в HeadHunter...
"Опыт разработки универсальной библиотеки визуальных компонентов в HeadHunter...MoscowJS
 
Телепортация MODX - MODX Meetup Minsk
Телепортация MODX - MODX Meetup MinskТелепортация MODX - MODX Meetup Minsk
Телепортация MODX - MODX Meetup MinskMODX Беларусь
 
Grpahite&amp;grafana
Grpahite&amp;grafanaGrpahite&amp;grafana
Grpahite&amp;grafanaLevon Avakyan
 
Tag Management (рекламный контейнер)
Tag Management (рекламный контейнер)Tag Management (рекламный контейнер)
Tag Management (рекламный контейнер)Michail Гаркунов
 
Синхронный MODX: как сделать настоящую синхронизацию и не застрелиться
Синхронный MODX: как сделать настоящую синхронизацию и не застрелитьсяСинхронный MODX: как сделать настоящую синхронизацию и не застрелиться
Синхронный MODX: как сделать настоящую синхронизацию и не застрелитьсяMODX Беларусь
 
Behat в PHP с использованием Behat и Mink
Behat в PHP с использованием Behat и MinkBehat в PHP с использованием Behat и Mink
Behat в PHP с использованием Behat и Minktyomo4ka
 
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17MoscowJS
 
Bootstrap 3. Адаптивная верстка для WordPress
Bootstrap 3. Адаптивная верстка для WordPressBootstrap 3. Адаптивная верстка для WordPress
Bootstrap 3. Адаптивная верстка для WordPressIgor Sazonov
 
Диагностика проблем в рабочей среде при помощи IntelliTrace и Visual Studio 2...
Диагностика проблем в рабочей среде при помощи IntelliTrace и Visual Studio 2...Диагностика проблем в рабочей среде при помощи IntelliTrace и Visual Studio 2...
Диагностика проблем в рабочей среде при помощи IntelliTrace и Visual Studio 2...Герман Криммель
 
Паттерны быстрой разработки WPF MVVM бизнес-приложений
Паттерны быстрой разработки WPF MVVM бизнес-приложенийПаттерны быстрой разработки WPF MVVM бизнес-приложений
Паттерны быстрой разработки WPF MVVM бизнес-приложенийGoSharp
 
CQRS на практике. В поиске точки масштабирования и новых метафор
CQRS на практике. В поиске точки масштабирования и новых метафорCQRS на практике. В поиске точки масштабирования и новых метафор
CQRS на практике. В поиске точки масштабирования и новых метафорAlexander Byndyu
 
What's new in Visual Studio 2012
What's new in Visual Studio 2012What's new in Visual Studio 2012
What's new in Visual Studio 2012InTRUEdeR
 
Андрей Фейгин. GTM Словами агентства.
Андрей Фейгин. GTM Словами агентства.Андрей Фейгин. GTM Словами агентства.
Андрей Фейгин. GTM Словами агентства.iProspect Russia
 

Semelhante a Как построить DOM (20)

Михаил Давыдов — JavaScript: События
Михаил Давыдов — JavaScript: СобытияМихаил Давыдов — JavaScript: События
Михаил Давыдов — JavaScript: События
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»
 
Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»Илья Ефимов «IoC/DI на примере Autofac»
Илья Ефимов «IoC/DI на примере Autofac»
 
"Опыт разработки универсальной библиотеки визуальных компонентов в HeadHunter...
"Опыт разработки универсальной библиотеки визуальных компонентов в HeadHunter..."Опыт разработки универсальной библиотеки визуальных компонентов в HeadHunter...
"Опыт разработки универсальной библиотеки визуальных компонентов в HeadHunter...
 
Телепортация MODX - MODX Meetup Minsk
Телепортация MODX - MODX Meetup MinskТелепортация MODX - MODX Meetup Minsk
Телепортация MODX - MODX Meetup Minsk
 
пр 14.docx
пр 14.docxпр 14.docx
пр 14.docx
 
Grpahite&amp;grafana
Grpahite&amp;grafanaGrpahite&amp;grafana
Grpahite&amp;grafana
 
Tag Management (рекламный контейнер)
Tag Management (рекламный контейнер)Tag Management (рекламный контейнер)
Tag Management (рекламный контейнер)
 
Синхронный MODX: как сделать настоящую синхронизацию и не застрелиться
Синхронный MODX: как сделать настоящую синхронизацию и не застрелитьсяСинхронный MODX: как сделать настоящую синхронизацию и не застрелиться
Синхронный MODX: как сделать настоящую синхронизацию и не застрелиться
 
Behat в PHP с использованием Behat и Mink
Behat в PHP с использованием Behat и MinkBehat в PHP с использованием Behat и Mink
Behat в PHP с использованием Behat и Mink
 
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
 
Deep Dive in Magento DI
Deep Dive in Magento DIDeep Dive in Magento DI
Deep Dive in Magento DI
 
Bootstrap 3. Адаптивная верстка для WordPress
Bootstrap 3. Адаптивная верстка для WordPressBootstrap 3. Адаптивная верстка для WordPress
Bootstrap 3. Адаптивная верстка для WordPress
 
Диагностика проблем в рабочей среде при помощи IntelliTrace и Visual Studio 2...
Диагностика проблем в рабочей среде при помощи IntelliTrace и Visual Studio 2...Диагностика проблем в рабочей среде при помощи IntelliTrace и Visual Studio 2...
Диагностика проблем в рабочей среде при помощи IntelliTrace и Visual Studio 2...
 
Паттерны быстрой разработки WPF MVVM бизнес-приложений
Паттерны быстрой разработки WPF MVVM бизнес-приложенийПаттерны быстрой разработки WPF MVVM бизнес-приложений
Паттерны быстрой разработки WPF MVVM бизнес-приложений
 
CQRS на практике. В поиске точки масштабирования и новых метафор
CQRS на практике. В поиске точки масштабирования и новых метафорCQRS на практике. В поиске точки масштабирования и новых метафор
CQRS на практике. В поиске точки масштабирования и новых метафор
 
What's new in Visual Studio 2012
What's new in Visual Studio 2012What's new in Visual Studio 2012
What's new in Visual Studio 2012
 
Андрей Фейгин. GTM Словами агентства.
Андрей Фейгин. GTM Словами агентства.Андрей Фейгин. GTM Словами агентства.
Андрей Фейгин. GTM Словами агентства.
 

Mais de 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
 
Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими рукамиRoman Dvornov
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееRoman Dvornov
 
CSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksCSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksRoman Dvornov
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksRoman Dvornov
 
CSSO – история ускорения
CSSO – история ускоренияCSSO – история ускорения
CSSO – история ускоренияRoman Dvornov
 
CSSO – compress CSS (english version)
CSSO – compress CSS (english version)CSSO – compress CSS (english version)
CSSO – compress CSS (english version)Roman Dvornov
 
CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)Roman Dvornov
 
CSSO — минимизируем CSS
 CSSO — минимизируем CSS CSSO — минимизируем CSS
CSSO — минимизируем CSSRoman Dvornov
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Карточный домик
Карточный домикКарточный домик
Карточный домикRoman Dvornov
 

Mais de Roman Dvornov (17)

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 – крутая платформа для крутых инструментов
 
Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими руками
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрее
 
CSS parsing: performance tips & tricks
CSS parsing: performance tips & tricksCSS parsing: performance tips & tricks
CSS parsing: performance tips & tricks
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricks
 
Парсим CSS
Парсим CSSПарсим CSS
Парсим CSS
 
CSSO – история ускорения
CSSO – история ускоренияCSSO – история ускорения
CSSO – история ускорения
 
CSSO – compress CSS (english version)
CSSO – compress CSS (english version)CSSO – compress CSS (english version)
CSSO – compress CSS (english version)
 
CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)CSSO — сжимаем CSS (часть 2)
CSSO — сжимаем CSS (часть 2)
 
CSSO — минимизируем CSS
 CSSO — минимизируем CSS CSSO — минимизируем CSS
CSSO — минимизируем CSS
 
Component Inspector
Component InspectorComponent Inspector
Component Inspector
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Карточный домик
Карточный домикКарточный домик
Карточный домик
 

Как построить DOM