DOM-шаблонизаторы – 

не только «быстро»
Июнь 2014
Роман Дворнов
Ostrovok.ru
О себе
• Работаю в ostrovok.ru
• Автор basis.js
2
Сегодня мы создаем
динамические интерфейсы
3
Динамические интерфейсы

=

работа с DOM
4
Построение интерфейса
=

создание DOM-фрагментов
и их композиция
5
Что можно использовать для
создания DOM-фрагментов?
6
Что можно использовать для
создания DOM-фрагментов?
• Руки ;)
6
Что можно использовать для
создания DOM-фрагментов?
• Руки ;)
• String-шаблонизаторы
6
Что можно использовать для
создания DOM-фрагментов?
• Руки ;)
• String-шаблонизаторы
• DOM-шаблонизаторы
6
String vs. DOM
7
String-шаблонизаторы
8
Описание шаблона =

набор строк + инструкции
9
10
<div class="entry">	
<h1>{{title}}</h1>	
<div class="body">	
{{body}}	
</div>	
</div>
… + title +	
… + body +	
…
String...
Не известно какая в итоге
получится DOM-структура 

и как она будет меняться
11
Зато достаточно
универсальный подход,
а HTML частный случай
12
Строковые шаблонизаторы
производят функции,
которые производят строки
13
После этого 

innerHTML + пост-процессинг
14
Пост-процессинг
• Получение ссылок на элементы
• Навешивание обработчиков событий
• Модификация DOM

(использование jQuery...
Пост-процессинг
самая медленная фаза
16
Процесс
• герерация HTML
• innerHTML
• пост-процессинг
17
Создание Обновление
• генерация HTML
• innerHTML
• пост-процесси...
Процесс
• герерация HTML
• innerHTML
• пост-процессинг
17
Создание Обновление
• генерация HTML
• innerHTML
• пост-процесси...
DOM-шаблонизаторы
18
19
Описание шаблона =

DOM узлы + инструкции
20
<div class="entry">	
{{title}}	
</div>
DOM шаблонизаторы
Атрибут
Текстовый узел
Элемент
Известно какая будет 

DOM-структура и как будет
меняться
21
... еще до построения
нативного DOM
22
Ориентированы
на работу с DOM*
23
* Но не обязательно производят только DOM
DOM-шаблонизаторы
производят и обслуживают
DOM-фрагменты
24
Знания о DOM структуре
позволяют использовать
оптимизации
25
Например
• cloneNode(true) – быстрое создание 

DOM-фрагмента
• обработка событий через один глобальный
capture-обработчик...
Процесс
• построение 

DOM-фрагмента или
cloneNode(true)
• DOM-операции
27
Создание Обновление
• DOM-операции
Работают быстрее
28
Могут проигрывать 

при генерации больших
фрагментов неизменяемой
верстки
29
Но выигрывают на
генерации повторяющихся
фрагментов
30
TodoMVC
31
100 items 1000 items
AngularJS 125 ms 1491 ms
Backbone 53 ms 510 ms
Knockout 39 ms 489 ms
jQuery 20 ms 184 ms
B...
Всегда выигрывают
на обновлении
32
Подробнее в докладе
Как построить DOM
33
tinyurl.com/build-dom
Уже используется в ...
• Ractive
• Basis.js
• Ember: HTMLBars (в разработке)
• Meteor
• React*
34
* нет шаблонизатора, но ...
Не холивара ради…
35
DOMString
Универсальное решение
для сайтов и
приложений, подходит
для сервера и клиента
Оптимально дл...
String-шаблонизаторы
36
DOM-шаблонизаторы
37
Развивая идеи
DOM-шаблонизации…
38
На примере basis.js
Абстрагирование 

от верстки
39
В коде
• Абстрагируемся от верстки
• Нет селекторов
• Нет указания CSS классов, имен тегов
• Нет HTML
• Нет стилей
40
Не знаем о разметке 

и как используются
значения
41
42
<div{el} class="example">	
{text}	
</div>
{	
el: <div>,	
text: #text,	
set: function(name, value){	
// black magic box	...
Не знаем какие классы
в разметке, не используем
селекторы в JavaScript
43
44
<div{el} class="example">	
<h1>{text}</h1>	
<ul{content}/>	
</div>
el = fragment.firstChild	
text = el.firstChild.first...
Подключение стилей
<b:style>
45
46
<b:style src="block.css"/>	
!
<div class="block block_{hidden}">	
{caption}	
</div>
Подключение стилей
.block	
{	
...	
...
Включение других шаблонов
<b:include>
47
48
<b:style src="./example.css"/>	
<div class="wrapper">	
<b:include src="./button.tmpl">	
<b:after ref="caption"> {count}...
Изоляция стилей
<b:isolate>
49
50
<b:style src="option.css"/>	
!
<div class="xo-bookings-change-status-popup-option
xo-bookings-change-status-popup-optio...
51
<b:style src="option.css"/>	
<b:isolate/>	
!
<div class="option {disabled} {hidden}">	
<span class="caption caption_{se...
В топку BEM?
52
В топку префиксы!
53
Но фишка не только в
префиксах…
54
Переопределение стилей
вместо добавления
модификаторов
55
56
Безопасное дополнение стилей
<b:style src="./button.css"/>	
<button class="button">	
click me	
</div>
button.tmpl
<b:is...
57
<b:isolate/>	
<b:style>	
.abc-foo { color: red; }	
.xyz-foo { color: blue; }	
</b:style>	
<div class="panel">	
<b:inclu...
58
Изоляция включений: результат
<b:style src="./foo.css?prefix=hs83shyf_abc-"/>	
<b:style src="./foo.css?prefix=hs83shyf_...
59
Пространства имен
<b:style src="./bootstrap.css" ns="bt"/>	
<b:style src="./glyphs.css" ns="glyph"/>	
<b:style src="./s...
Гарантия уникальности классов

=

более сильные оптимизации
60
61
Например
<b:isolate/>	
<b:style src="./style.css"/>	
<div class="foo bar">	
..	
</div>
.foo {	
color: red;	
width: 100p...
62
Оптимизация: слияние стилей
<b:isolate/>	
<b:style src="./style.css"/>	
<div class="baz">	
..	
</div>
.baz {	
/* color:...
И мы продолжаем
экспериментировать ;)
63
«Эээ… но у нас же есть
Web Components…»
64
Кто-то из зала
Все таки их пока нет* ;)
65
* в процессе разработки и имплементации
Web Components –
деклативная обертка для
инкапсулированных ресурсов 

(DOM, CSS, JS)
66
В моем понимании
В простом случае:
!
1 DOM фрагмент
+
DOM-манипуляции*
67
* мог бы делать шаблонизатор
В комплексном случае:
!
Много фрагментов
+
возвращаемся к проблеме
шаблонизации
68
Web Components
69
Хорошо для виджетов
(проигрыватели, карты и т.д)
Web Components
70
Не решает проблем самих
компонент и приложений
Не совсем про шаблонизатор, 

но мы храним
шаблоны в отдельных файлах
71
И остальные тоже скоро будут так делать ;)
Абстрагирование
+
внешние файлы
=
Live update
72
Live update –
обновление DOM-фрагментов 

без перезагрузки страницы
73
74
<div class="sidebar">	
...	
<ul class="list">	
<li>item 1</li>	
<li>item 2</li>	
</ul>	
...	
</div>
<div class="list-wr...
74
<div class="sidebar">	
...	
<ul class="list">	
<li>item 1</li>	
<li>item 2</li>	
</ul>	
...	
</div>
<div class="list-wr...
74
<div class="sidebar">	
...	
<ul class="list">	
<li>item 1</li>	
<li>item 2</li>	
</ul>	
...	
</div>
<div class="list-wr...
Live update
экономит время и
разгоняет разработку
75
Live update
+
Логика
=
Адаптивные View
76
Абстрагирование
+
Наборы шаблонов
=
Темы
77
78
Результат
basis.template.theme('base').define({	
foo: resource('path/to/file.tmpl'),	
...	
});	
basis.template.theme('m...
Тема = HTML + CSS
79
Тоже
без перезагрузки страницы
80
Но это побочный эффект ;)
Экземпляры шаблонов
хранят мета-информацию*
81
* только в dev-режиме
Это дает возможность
определять к какому шаблону
относится DOM-узел
82
Heat map

показывает где и 

как часто меняется DOM
83
Demo
84
github.com/lahmatiy/template-demos
Вне шаблонизатора
85
Анализ и выявление проблем
• какие классы используются в разметке,
но их нет в стилях
• какие селекторы никогда не сработа...
Оптимальная сборка
• Минимизация классов
• Удаление разметки и стилей, которые
не используются
• и т.д.
87
И многое другое…
88
И все благодаря DOM
89
В строковых шаблонизаторах
многое из этого невозможно
или крайне сложно
90
DOM это круто!
91
Главное начать 

думать в терминах DOM
92
Попробуйте ;)
93
Вопросы?
94
Роман Дворнов
@rdvornov
rdvornov@gmail.com
basis.js
basisjs.com
github.com/basisjs
Upcoming SlideShare
Loading in …5
×

DOM-шаблонизаторы – не только "быстро"

2,804 views

Published on

Шаблонизация основанная на работе с DOM становится трендом: React, Ractive, Basis.js уже используют этот подход, другие идут в эту сторону. Главным преимуществом подхода считается скорость, но оно далеко не единственное!
В докладе немного рассказано о возможностях, что дает DOM подход.

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,804
On SlideShare
0
From Embeds
0
Number of Embeds
162
Actions
Shares
0
Downloads
16
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

DOM-шаблонизаторы – не только "быстро"

  1. 1. DOM-шаблонизаторы – 
 не только «быстро» Июнь 2014 Роман Дворнов Ostrovok.ru
  2. 2. О себе • Работаю в ostrovok.ru • Автор basis.js 2
  3. 3. Сегодня мы создаем динамические интерфейсы 3
  4. 4. Динамические интерфейсы
 =
 работа с DOM 4
  5. 5. Построение интерфейса =
 создание DOM-фрагментов и их композиция 5
  6. 6. Что можно использовать для создания DOM-фрагментов? 6
  7. 7. Что можно использовать для создания DOM-фрагментов? • Руки ;) 6
  8. 8. Что можно использовать для создания DOM-фрагментов? • Руки ;) • String-шаблонизаторы 6
  9. 9. Что можно использовать для создания DOM-фрагментов? • Руки ;) • String-шаблонизаторы • DOM-шаблонизаторы 6
  10. 10. String vs. DOM 7
  11. 11. String-шаблонизаторы 8
  12. 12. Описание шаблона =
 набор строк + инструкции 9
  13. 13. 10 <div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div> </div> … + title + … + body + … String-шаблонизаторы Описание (handlebars) Интерпретация
  14. 14. Не известно какая в итоге получится DOM-структура 
 и как она будет меняться 11
  15. 15. Зато достаточно универсальный подход, а HTML частный случай 12
  16. 16. Строковые шаблонизаторы производят функции, которые производят строки 13
  17. 17. После этого 
 innerHTML + пост-процессинг 14
  18. 18. Пост-процессинг • Получение ссылок на элементы • Навешивание обработчиков событий • Модификация DOM
 (использование jQuery-like плагинов, вставка DOM фрагментов etc) • и т.д. 15
  19. 19. Пост-процессинг самая медленная фаза 16
  20. 20. Процесс • герерация HTML • innerHTML • пост-процессинг 17 Создание Обновление • генерация HTML • innerHTML • пост-процессинг
  21. 21. Процесс • герерация HTML • innerHTML • пост-процессинг 17 Создание Обновление • генерация HTML • innerHTML • пост-процессинг =
  22. 22. DOM-шаблонизаторы 18
  23. 23. 19 Описание шаблона =
 DOM узлы + инструкции
  24. 24. 20 <div class="entry"> {{title}} </div> DOM шаблонизаторы Атрибут Текстовый узел Элемент
  25. 25. Известно какая будет 
 DOM-структура и как будет меняться 21
  26. 26. ... еще до построения нативного DOM 22
  27. 27. Ориентированы на работу с DOM* 23 * Но не обязательно производят только DOM
  28. 28. DOM-шаблонизаторы производят и обслуживают DOM-фрагменты 24
  29. 29. Знания о DOM структуре позволяют использовать оптимизации 25
  30. 30. Например • cloneNode(true) – быстрое создание 
 DOM-фрагмента • обработка событий через один глобальный capture-обработчик на документе для каждого уникального события 26
  31. 31. Процесс • построение 
 DOM-фрагмента или cloneNode(true) • DOM-операции 27 Создание Обновление • DOM-операции
  32. 32. Работают быстрее 28
  33. 33. Могут проигрывать 
 при генерации больших фрагментов неизменяемой верстки 29
  34. 34. Но выигрывают на генерации повторяющихся фрагментов 30
  35. 35. TodoMVC 31 100 items 1000 items AngularJS 125 ms 1491 ms Backbone 53 ms 510 ms Knockout 39 ms 489 ms jQuery 20 ms 184 ms Backbone + basis.js templates 18 ms 202 ms basis.js 8 ms 95 ms
  36. 36. Всегда выигрывают на обновлении 32
  37. 37. Подробнее в докладе Как построить DOM 33 tinyurl.com/build-dom
  38. 38. Уже используется в ... • Ractive • Basis.js • Ember: HTMLBars (в разработке) • Meteor • React* 34 * нет шаблонизатора, но внутри DOM-подход
  39. 39. Не холивара ради… 35 DOMString Универсальное решение для сайтов и приложений, подходит для сервера и клиента Оптимально для больших динамических одностраничных приложений
  40. 40. String-шаблонизаторы 36
  41. 41. DOM-шаблонизаторы 37
  42. 42. Развивая идеи DOM-шаблонизации… 38 На примере basis.js
  43. 43. Абстрагирование 
 от верстки 39
  44. 44. В коде • Абстрагируемся от верстки • Нет селекторов • Нет указания CSS классов, имен тегов • Нет HTML • Нет стилей 40
  45. 45. Не знаем о разметке 
 и как используются значения 41
  46. 46. 42 <div{el} class="example"> {text} </div> { el: <div>, text: #text, set: function(name, value){ // black magic box } } Описание Интерфейс к экземпляру Работаем с интерфейсом Отдаем значения, 
 но что там происходит не знаем
  47. 47. Не знаем какие классы в разметке, не используем селекторы в JavaScript 43
  48. 48. 44 <div{el} class="example"> <h1>{text}</h1> <ul{content}/> </div> el = fragment.firstChild text = el.firstChild.firstChild content = el.lastChild Описание Получение ссылок Жизнь без селекторов (пути генерирует шаблонизатор)
  49. 49. Подключение стилей <b:style> 45
  50. 50. 46 <b:style src="block.css"/> ! <div class="block block_{hidden}"> {caption} </div> Подключение стилей .block { ... } .block_hidden { ... } block.cssblock.tmpl
  51. 51. Включение других шаблонов <b:include> 47
  52. 52. 48 <b:style src="./example.css"/> <div class="wrapper"> <b:include src="./button.tmpl"> <b:after ref="caption"> {count}</b:after> </b:include> </div> Включение шаблонов Результат example.tmpl <b:style src="./button.css"/> <b:style src="./example.css"/> <div class="wrapper"> <button class="button"> {caption} {count} </button> </div> <b:style src="./button.css"/> <button class="button"> {caption} </button> button.tmpl
  53. 53. Изоляция стилей <b:isolate> 49
  54. 54. 50 <b:style src="option.css"/> ! <div class="xo-bookings-change-status-popup-option xo-bookings-change-status-popup-option_{disabled} xo-bookings-change-status-popup-option_{hidden}"> <span class="xo-bookings-change-status-popup- option__caption xo-bookings-change-status-popup- option__caption_{selected}"> {title} </span> </div> До
  55. 55. 51 <b:style src="option.css"/> <b:isolate/> ! <div class="option {disabled} {hidden}"> <span class="caption caption_{selected}"> {title} </span> </div> После
  56. 56. В топку BEM? 52
  57. 57. В топку префиксы! 53
  58. 58. Но фишка не только в префиксах… 54
  59. 59. Переопределение стилей вместо добавления модификаторов 55
  60. 60. 56 Безопасное дополнение стилей <b:style src="./button.css"/> <button class="button"> click me </div> button.tmpl <b:isolate/> <b:style> .button { color: green; } </b:style> <b:include src="./button.tmpl"/> ok-button.tmpl <b:isolate/> <b:style> .button { color: red; } </b:style> <b:include src="./button.tmpl"/> cancel-button.tmpl
  61. 61. 57 <b:isolate/> <b:style> .abc-foo { color: red; } .xyz-foo { color: blue; } </b:style> <div class="panel"> <b:include src="./foo.tmpl" isolate="abc-"/> <b:include src="./foo.tmpl" isolate="xyz-"/> </div> Изоляция включений <b:style src="./foo.css"/> <div class="foo"> example </div> example.tmpl foo.tmpl
  62. 62. 58 Изоляция включений: результат <b:style src="./foo.css?prefix=hs83shyf_abc-"/> <b:style src="./foo.css?prefix=hs83shyf_xyz-"/> <b:style> .hs83shyf_abc-foo { color: red; } .hs83shyf_xyz-foo { color: blue; } </b:style> <div class="hs83shyf_panel"> <div class="hs83shyf_abc-foo"> example </div> <div class="hs83shyf_xyz-foo"> example </div> </div>
  63. 63. 59 Пространства имен <b:style src="./bootstrap.css" ns="bt"/> <b:style src="./glyphs.css" ns="glyph"/> <b:style src="./style.css"/> ! <div class="glyph:active bt:active active"> ... </div> (Побочный продукт методики)
  64. 64. Гарантия уникальности классов
 =
 более сильные оптимизации 60
  65. 65. 61 Например <b:isolate/> <b:style src="./style.css"/> <div class="foo bar"> .. </div> .foo { color: red; width: 100px; } .bar { color: green; } example.tmpl style.css
  66. 66. 62 Оптимизация: слияние стилей <b:isolate/> <b:style src="./style.css"/> <div class="baz"> .. </div> .baz { /* color: red; */ width: 100px; color: green; } example.tmpl style.css
  67. 67. И мы продолжаем экспериментировать ;) 63
  68. 68. «Эээ… но у нас же есть Web Components…» 64 Кто-то из зала
  69. 69. Все таки их пока нет* ;) 65 * в процессе разработки и имплементации
  70. 70. Web Components – деклативная обертка для инкапсулированных ресурсов 
 (DOM, CSS, JS) 66 В моем понимании
  71. 71. В простом случае: ! 1 DOM фрагмент + DOM-манипуляции* 67 * мог бы делать шаблонизатор
  72. 72. В комплексном случае: ! Много фрагментов + возвращаемся к проблеме шаблонизации 68
  73. 73. Web Components 69 Хорошо для виджетов (проигрыватели, карты и т.д)
  74. 74. Web Components 70 Не решает проблем самих компонент и приложений
  75. 75. Не совсем про шаблонизатор, 
 но мы храним шаблоны в отдельных файлах 71 И остальные тоже скоро будут так делать ;)
  76. 76. Абстрагирование + внешние файлы = Live update 72
  77. 77. Live update – обновление DOM-фрагментов 
 без перезагрузки страницы 73
  78. 78. 74 <div class="sidebar"> ... <ul class="list"> <li>item 1</li> <li>item 2</li> </ul> ... </div> <div class="list-wrapper"> <h2>Header</h2> <ul class="list"> </ul> </div> Замена DOM-фрагмента Старый DOM Новый DOM
  79. 79. 74 <div class="sidebar"> ... <ul class="list"> <li>item 1</li> <li>item 2</li> </ul> ... </div> <div class="list-wrapper"> <h2>Header</h2> <ul class="list"> </ul> </div> insertBefore Замена DOM-фрагмента Старый DOM Новый DOM
  80. 80. 74 <div class="sidebar"> ... <ul class="list"> <li>item 1</li> <li>item 2</li> </ul> ... </div> <div class="list-wrapper"> <h2>Header</h2> <ul class="list"> </ul> </div> replaceChild insertBefore Замена DOM-фрагмента Старый DOM Новый DOM
  81. 81. Live update экономит время и разгоняет разработку 75
  82. 82. Live update + Логика = Адаптивные View 76
  83. 83. Абстрагирование + Наборы шаблонов = Темы 77
  84. 84. 78 Результат basis.template.theme('base').define({ foo: resource('path/to/file.tmpl'), ... }); basis.template.theme('myTheme').define({ foo: resource('path/to/file.tmpl'), ... }); ! var view = new basis.ui.Node({ template: basis.template.get('foo'), ... }); Набор шаблонов 
 базовой темы Еще одна тема Использование 
 шаблона по имени
  85. 85. Тема = HTML + CSS 79
  86. 86. Тоже без перезагрузки страницы 80 Но это побочный эффект ;)
  87. 87. Экземпляры шаблонов хранят мета-информацию* 81 * только в dev-режиме
  88. 88. Это дает возможность определять к какому шаблону относится DOM-узел 82
  89. 89. Heat map
 показывает где и 
 как часто меняется DOM 83
  90. 90. Demo 84 github.com/lahmatiy/template-demos
  91. 91. Вне шаблонизатора 85
  92. 92. Анализ и выявление проблем • какие классы используются в разметке, но их нет в стилях • какие селекторы никогда не сработают • конфликты стилей • и т.д. 86
  93. 93. Оптимальная сборка • Минимизация классов • Удаление разметки и стилей, которые не используются • и т.д. 87
  94. 94. И многое другое… 88
  95. 95. И все благодаря DOM 89
  96. 96. В строковых шаблонизаторах многое из этого невозможно или крайне сложно 90
  97. 97. DOM это круто! 91
  98. 98. Главное начать 
 думать в терминах DOM 92
  99. 99. Попробуйте ;) 93
  100. 100. Вопросы? 94 Роман Дворнов @rdvornov rdvornov@gmail.com basis.js basisjs.com github.com/basisjs

×