SlideShare uma empresa Scribd logo
1 de 164
Baixar para ler offline
Жизнь в изоляции
Роман Дворнов
Avito
Санкт-Петербург 2015
Работаю в Avito
Делаю SPA
Автор basis.js
Я…
За любую движуху, 

кроме голодовки ;)
Проблема
Большие сайты и SPA
4
5
Мамонта нужно есть по частям…
Компонентный подход 

и модульность – возможность
решать большую проблему
порционно
6
Основная задача:
избежать конфликтов
7
Инкапсуляция
8
«обеспечение доступности главного … путем
помещения всего мешающего, второстепенного
в некую условную капсулу (чёрный ящик)»
ru.wikipedia.org/wiki/Инкапсуляция
Способы инкапсуляции
9
Способы инкапсуляции
• Скрипты – замыкания, модули (ES6)
9
Способы инкапсуляции
• Скрипты – замыкания, модули (ES6)
• Разметка – неймспейсы (например, SVG)
9
Способы инкапсуляции
• Скрипты – замыкания, модули (ES6)
• Разметка – неймспейсы (например, SVG)
• Стили – ???
9
Изоляция стилей
4 подхода
11
Соглашение
Подход №1
Некоторая договоренность,
описывающая принцип
именования классов
13
блок__элемент--модификатор
14
Например
Это БЭМ, но все далее так же справедливо

и для OOCSS, SMACSS, SUIT, ACSS и т.д.
Изоляция достигается путем
придумывания уникальных имен
15
«Есть только две трудные задачи в
области информатики: инвалидация
кеша и придумывание названий.»
16
– Фил Карлтон
17
Знаешь сколько верстальщики тратят на
придумывание одного имени класса?
Целый день.
Целый день, Карл!
Это не проблема, когда мало
уникальных компонент
18
Универсальный компонент
v.s.
Компонент под задачу
19
20
21
<div class="app-bookings-change-status-popup-option 

app-bookings-change-status-popup-option_{disabled} 

app-bookings-change-status-popup-option_{hidden}">	
<span class="app-bookings-change-status-popup-option__caption
app-bookings-change-status-popup-option__caption_{selected}">	
{title}	
</span>	
</div>
Проблема, когда уникальных
компонент много
Реальный пример из жизни
Другие проблемы
• Уникальность обеспечивается человеком
• Сложность автоматизированного анализа
• Нет механизмов интеграции сторонней
верстки в свою или свою в чужое окружение
• …
22
Основная проблема –
человеческий фактор
23
Если правило можно нарушить –
оно будет нарушено
24
Нельзя проверить правильно ли
вы делаете, это может сказать
только человек
25
Привет, субъективное мнение!
Плюсы
• Хоть какая-то система
• Дешево для внедрения
26
Не смотря на популярность –
так себе решение*
27
* для сложных проектов
Технология
Подход №2
Shadow DOM
29
часть Web Components
w3c.github.io/webcomponents/spec/shadow/
Shadow DOM – 

возможность инкапсулировать
DOM-фрагмент
30
31
Все созданные ранее API не
видят содержимое Shadow Tree
32
А там может быть любая разметка
и стили к ней
Любая вложенность
Любая вложенность
Shadow DOM – 

это всегда JavaScript
34
35
function init(container) {	
var shadowRoot = container.createShadowRoot();	
!
var content = document.createElement('div');	
content.innerHTML = 'some markup';	
!
var styles = document.createElement('style');	
styles.textContent = '/* some css */';	
!
shadowRoot.appendChild(styles);	
shadowRoot.appendChild(content);	
}
Создаем корень Shadow Tree
36
function init(container) {	
var shadowRoot = container.createShadowRoot();	
!
var content = document.createElement('div');	
content.innerHTML = 'some markup';	
!
var styles = document.createElement('style');	
styles.textContent = '/* some css */';	
!
shadowRoot.appendChild(styles);	
shadowRoot.appendChild(content);	
}
Создаем DOM фрагмент
37
function init(container) {	
var shadowRoot = container.createShadowRoot();	
!
var content = document.createElement('div');	
content.innerHTML = 'some markup';	
!
var styles = document.createElement('style');	
styles.textContent = '/* some css */';	
!
shadowRoot.appendChild(styles);	
shadowRoot.appendChild(content);	
}
Создаем стили
38
function init(container) {	
var shadowRoot = container.createShadowRoot();	
!
var content = document.createElement('div');	
content.innerHTML = 'some markup';	
!
var styles = document.createElement('style');	
styles.textContent = '/* some css */';	
!
shadowRoot.appendChild(styles);	
shadowRoot.appendChild(content);	
}
Вставляем все в Shadow Tree
Custom Elements позволяют
абстрагироваться от нюансов
реализации
39
www.w3.org/TR/custom-elements/
Для них также нужен JavaScript
Проблема изоляции решена?
40
Миф:
Shadow DOM обеспечивает
полную изоляцию стилей
41
На текущий момент
А Shadow DOM-то – протекает
• Часть стилей наследуется от хоста

font, line-height, color и т.д.
• Можно стилизовать извне, используя
комбинатор >>> (бывш. /deep/ и ^^)
42
dev.w3.org/csswg/css-scoping/
43
Хорошая новость:
Все производители браузеров
намерены внедрять Shadow DOM
44
встреча Google, Mozilla, Apple и Microsoft
45
Но текущий дизайн «не очень»…
Надо «все» переделать
• Будет два режима open (то что сейчас) 

и close (более закрытый)
• Отказ от комбинатора >>> (м.б. будут слоты)
• Потребуется переделать текущий API
• ...
46
tinyurl.com/oqkv5u6
Плюсы
• Честная изоляция (особенно в режиме close)
• Браузерное решение (возможный стандарт)
47
Минусы
• Сложная концепция
• Требуется JavaScript
• Трудно полифилить
• Спецификация далека от завершения, 

все еще поменяется
48
Пока рано использовать,
нужно еще подумать…
49
Инлайн-стили
Подход №3
Предложение от команды React –
пишем CSS в JavaScript
51
speakerdeck.com/vjeux/react-css-in-js
speakerdeck.com/vjeux/react-css-in-js-react-france-meetup
52
var React = require('react');	
!
var styles = {	
button: {	
color: 'white',	
backgroundColor: 'red'	
}	
};	
!
var MyButton = React.createClass({	
render: function() {	
return <button style={styles.button}>Hello, world!</button>	
}	
});
А как же каскад, 

псевдоклассы, 

медиавыражения и т.д.?
53
54
function merge(...args){	
return Object.assign({}, ...args);	
}	
!
var styles = {	
// ...	
disabled: {	
opacity: .5	
}	
};	
!
<button style={merge(	
styles.button,	
condition && styles.disabled	
)}>Hello, world!</button>	
Каскад
.button {	
...	
}	
!
.disabled {	
opacity: .5;	
}
55
.button {	
background-color: gray;	
}	
.button:hover {	
background-color: red;	
}	
!
<button 	
onMouseEnter={function(){ this.setState({ hover: true }); }}	
onMouseLeave={function(){ this.setState({ hover: false }); }} 	
style={{ background: this.state.hover ? 'red' : 'gray' }}>	
Hello, world!	
</button>	
:hover
56
.button {	
width: 600px;	
}	
@media (max-device-width: 1024px) {	
.button {	
width: 300px;	
}	
}	
!
<button style={{ width: window.innerWidth > 1024 ? 600 : 300 }}>	
Hello, world!	
</button>	
Media Queries
+ обработчик на window.resize
57
Реакция 

здорового человека
Они убили Кенни

лучшее в CSS
58
Плюсы
• Изолированные стили без селекторов
• Все возможности JavaScript для стилей
• Нет проблемы специфичности
59
Минусы
• Подходит только для решений в стиле React
• Полное слияние логики и представления
• Нельзя использовать пре- и пост-процессоры
• Нельзя применять анализ и оптимизировать
• Бесполезность браузерных Developer Tools
60
61
Шурик, Вы комсомолец?
Это же не наш метод! Где гуманизм?
Процессинг
Подход №4
Пре- и пост-процессоры:
транспиляция, трансформация,
оптимизация, минификация…
63
Скрипты Разметка Стили
«Проблема»:
процессоры рассматриваются
в рамках одной технологии
64
Но если работать с технологиями
совместно, можно получить больше
65
Рассмотрим
Basis
Ember
React
66
Basis
Подход №4.1
DOM-шаблонизаторы –

не только «быстро»
68
tinyurl.com/domtemplates
Год назад в докладе
Тогда была только идея, 

теперь есть реализация и опыт
69
Предусловия
• В JavaScript не используем CSS-классы

(абстрагируемся от верстки)
• В шаблонах явно указываются используемые
файлы стилей (нет глобальных)
70
71
<b:style src="block.css"/>	
<div class="block block_{hidden}">	
{caption}	
</div>
.block { … }	
.block_hidden { … }
block.css
block.tmpl
Вот так
Инструкция шаблонизатору 

о необходимости
подключить файл стилей
Префикс b: (сокр. от basis)
стандартный механизм
неймспейсов в XML
(для избежания конфликта
имен)
Взяв любой шаблон, 

мы «знаем» всю его разметку 

и используемые им стили
72
Изоляция включается
инструкцией шаблонизатору
<b:isolate/>
73
Изоляция достигается путем
добавления уникального
префикса всем именам классов
74
75
<b:style src="block.css"/>	
<b:isolate/>	
<div class="block block_{hidden}">	
{caption}	
</div>
.block { … }	
.block_hidden { … }
block.css
block.tmpl
Добавляем инструкцию
76
<b:style src="block.css"/>	
<b:isolate/>	
<div class="block block_{hidden}">	
{caption}	
</div>
.block { … }	
.block_hidden { … }
block.css
block.tmpl
Отдаем шаблонизатору
!
!
Шаблонизатор
Пре-процессор
77
Шаблонизатор преобразует разметку и стили
<b:style src="block.css"/>	
<b:isolate/>	
<div class="block block_{hidden}">	
{caption}	
</div>
.block { … }	
.block_hidden { … }
block.css
block.tmpl
!
!
Шаблонизатор
Пре-процессор
77
Шаблонизатор преобразует разметку и стили
<link href="block.css?prefix=jc1hsy_">	
!
<div class="jc1hsy_block jc1hsy_block_{hidden}">	
{caption}	
</div>
.jc1hsy_block { … }	
.jc1hsy_block_hidden { … }
block.css?prefix=jc1hsy_
Разметка
!
!
Шаблонизатор
Пре-процессор
Префиксы генерируются
случайным образом, 

вид зависит от задачи
78
Еще вернемся к этому
Непредсказуемость префикса
лишает возможности «хакать»
верстку извне
79
Честный АНБ – без вариантов
80
<div class="app-bookings-change-status-popup-option 

app-bookings-change-status-popup-option_{disabled} 

app-bookings-change-status-popup-option_{hidden}">	
<span class="app-bookings-change-status-popup-option__caption
app-bookings-change-status-popup-option__caption_{selected}">	
{title}	
</span>	
</div>
Помните пример?
81
<b:style src="option.css"/>	
<b:isolate/>	
!
<div class="option option_{disabled} option_{hidden}">	
<span class="caption caption_{selected}">	
{title}	
</span>	
</div>
То же с изоляцией
Фишка не только в
префиксах…
82
Переопределение стилей
вместо добавления 

новых классов
83
84
Безопасное дополнение стилей
<b:style src="button.css"/>	
<button class="button">	
click me	
</button>
button.tmpl
<b:isolate/>	
<b:style>	
.button { background: green; }	
</b:style>	
<b:include src="./button.tmpl"/>
ok-button.tmpl
<b:isolate/>	
<b:style>	
.button { background: red; }	
</b:style>	
<b:include src="./button.tmpl"/>
cancel-button.tmpl
85
Безопасное дополнение стилей
<b:isolate/>	
<b:style>	
.button { background: green; }	
</b:style>	
<b:include src="./button.tmpl"/>
ok-button.tmpl
<b:isolate/>	
<b:style>	
.button { background: red; }	
</b:style>	
<b:include src="./button.tmpl"/>
cancel-button.tmpl
<b:style src="button.css"/>	
<button class="button">	
click me	
</button>
button.tmpl
85
Безопасное дополнение стилей
<b:isolate/>	
<b:style>	
.button { background: green; }	
</b:style>	
<b:include src="./button.tmpl"/>
ok-button.tmpl
<b:isolate/>	
<b:style>	
.button { background: red; }	
</b:style>	
<b:include src="./button.tmpl"/>
cancel-button.tmpl
<style>	
.jkc83s_button { … }	
.jkc83s_button { background: green; }	
</style>	
<button class="jkc83s_button">	
click me	
</button>
<style>	
.h9sg2n_button { … }	
.h9sg2n_button { background: green; }	
</style>	
<button class="h9sg2n_button">	
click me	
</button>
!
Стили раздельно для примера, 

в сборке все стили
объединяются и сжимаются
86
Масштабируем подход:
изоляция включаемой верстки
87
88
<b:isolate/>	
<b:style>	
.example-foo { color: red; }	
</b:style>	
<div class="panel">	
<b:include src="foo.tmpl" isolate="example-"/>	
<b:include src="foo.tmpl" isolate>	
<b:style src="nested.css"/>	
</b:include>	
</div>
example.tmpl
<b:style src="foo.css"/>	
<div class="foo">	
example	
</div>
foo.tmpl
Можно указывать конкретный префикс для
обращения вне включения, или не указывать 

и добавлять стили внутри инструкции включения
Изолируем включения
89
<link href="foo.css?prefix=hs83shyf_example-">	
<link href="foo.css?prefix=hs83shyf_y0dk7x_">	
<link href="nested.css?prefix=hs83shyf_y0dk7x_">	
<style>	
.hs83shyf_example-foo { color: red; }	
</style>	
<div class="hs83shyf_panel">	
<div class="hs83shyf_example-foo">	
example	
</div>	
<div class="hs83shyf_y0dk7x_foo">	
example	
</div>	
</div>
90
<link href="foo.css?prefix=hs83shyf_example-">	
<link href="foo.css?prefix=hs83shyf_y0dk7x_">	
<link href="nested.css?prefix=hs83shyf_y0dk7x_">	
<style>	
.hs83shyf_example-foo { color: red; }	
</style>	
<div class="hs83shyf_panel">	
<div class="hs83shyf_example-foo">	
example	
</div>	
<div class="hs83shyf_y0dk7x_foo">	
example	
</div>	
</div>
3 изолированные области имен
в одной разметке!
CSS неймспейсы:
изоляция файлов стилей
91
92
<b:style src="bootstrap.css" ns="bt"/>	
<b:style src="icons.css" ns="icon"/>	
<b:style src="style.css"/>	
!
<div class="active">	
<span class="icon icon:active"></span>	
<button class="bt:btn bt:active">	
Button	
</button>	
</div>
Решаем проблему конфликта имен
93
<link href="bootstrap.css?prefix=iv7z2b_">	
<link href="icons.css?prefix=jasdhb_">	
<link href="style.css">	
!
<div class="active">	
<span class="icon jasdhb_active"></span>	
<button class="iv7z2b_btn iv7z2b_active">	
Button	
</button>	
</div>
Имена из разных файлов стилей не пересекаются
94
<link href="bootstrap.css?prefix=iv7z2b_">	
<link href="icons.css?prefix=jasdhb_">	
<link href="style.css">	
!
<div class="active">	
<span class="icon jasdhb_active"></span>	
<button class="iv7z2b_btn iv7z2b_active">	
Button	
</button>	
</div>
Знаем какой класс из какого файла
Кое что еще
95
Есть же еще есть 

пост-процессинг!
96
97
PostCSS
множество плагинов
csso
структурная оптимизация
…
Например
Оптимизации
98
99
.jkc83s_button {	
width: 100px;	
color: green;	
}
.jkc83s_button {	
color: red;	
width: 100px;	
}	
.jkc83s_button {	
color: green;	
}
csso
csso умеет объединять блоки
с одинаковым селектором
100
.foo {	
color: red;	
width: 100px;	
}	
.bar {	
color: green;	
}
Но в таком случае бессилен
селекторы разные
Понимание границ верстки дает
возможность для больших
оптимизаций
101
Границы обеспечивает изоляция стилей
102
<b:style src="style.css"/>	
<b:isolate/>	
!
<div class="foo bar">	
...	
</div>
.foo {	
color: red;	
width: 100px;	
}	
.bar {	
color: green;	
}
example.tmpl style.css
У нас есть все информация об использовании
foo и bar встречаются только 

на одном элементе
103
<b:style src="style.css"/>	
<b:isolate/>	
!
<div class="s82jhs">	
...	
</div>
.s82jhs {	
color: red;	
width: 100px;	
}	
.s82jhs {	
color: green;	
}
example.tmpl style.css
Можно склеить
.foo + .bar
104
.s82jhs {	
width: 100px;	
color: green;	
}
example.tmpl style.css
<b:style src="style.css"/>	
<b:isolate/>	
!
<div class="s82jhs">	
...	
</div>
Дальше за дело снова берется csso
Поиск ошибок и
ликвидация мертвого кода
105
106
<b:style src="example.css"/>	
!
<span class="foo never-used">	
...	
</span>	
.foo {	
/* ... */	
}	
.dead-style {	
/* ... */	
}	
example.tmpl example.css
Если класс используется в разметке, но
не используется в стилях или наоборот…
Не используемые имена классов
107
Инструменты нам скажут об этом
Проблемы отладки
108
109
Длинные префиксы,
трудно искать исходник
Нет ссылки на
оригинальный файл стилей
Префиксы
110
Мы определяем вид префикса,
в зависимости от окружения
111
В режиме разработки
используются префиксы вида
iNNN__
112
Где NNN – номер шаблона, часто совпадает
между перезагрузками страницы
113
Короткие префиксы, 

легко отличать друг от друга
В боевой среде

используются base36 хеши
h5fjy1bkfb4zcskh__
114
115
function generatePrefix(){	
function base36(num){	
return Math.round(num).toString(36);	
}	
!
// префикс должен начинаться с буквы	
var result = base36(10 + 25 * Math.random());	
!
while (result.length < 16)	
result += base36(new Date * Math.random());	
!
return result.substr(0, 16);	
}
Вероятность пересечения

1 / 5 747 921 912 739 067 000 000 000
Функция генерации префикса
Трансформация имен классов
116
Трансформация имен классов
• В шаблоне:

.example
116
Трансформация имен классов
• В шаблоне:

.example
• В документе – режим разработки:

.i123__example
116
Трансформация имен классов
• В шаблоне:

.example
• В документе – режим разработки:

.i123__example
• В документе – боевая среда:

.h5fjy1bkfb4zcskh__example
116
Трансформация имен классов
• В шаблоне:

.example
• В документе – режим разработки:

.i123__example
• В документе – боевая среда:

.h5fjy1bkfb4zcskh__example
• В документе – боевая среда + сжатие имен:

.Gh
116
117
Наша верстка в боевой среде
Поиск и ссылка на источник
118
Видео
119
Инструменты могут решить проблему поиска
Подробнее в докладе «SPA инструменты»
Видео
119
Инструменты могут решить проблему поиска
Подробнее в докладе «SPA инструменты»
120
Но как быть с информацией
в Developer Tools?
121
.example {	
/* … */	
}	
!
style.css
Исходный файл стилей
122
.jdf9gd__example {	
/* … */	
}	
!
!
style.css?prefix=jdf9gd__
Подставляем префикс – получаем новый файл
123
.jdf9gd__example {	
/* … */	
}	
!
/*# sourceURL=style.css?prefix=jdf9gd__ */	
!
style.css?prefix=jdf9gd__
Добавляем sourceURL
Имя сгенерированного
файла
124
.jdf9gd__example {	
/* … */	
}	
!
/*# sourceURL=style.css?prefix=jdf9gd__ */	
/*# sourceMappingURL=data:application/json;base64,... */	
style.css?prefix=jdf9gd__
Добавляем карту кода
Содержимое

карты кода в base64
125
btoa(	
JSON.stringify({	
"version": 3,	
"sources": ["style.css"],	
"mappings":	
"AAAA" + ";AACA".repeat(css.split('n').length) 	
})	
)
Генерация карты с построчным соответствием
Оригинальное имя файла
без префикса
Повторяем ";AACA" столько раз, сколько строк
126
Не забудьте включить карты кода для CSS
127
Ссылка на оригинальный файл стилей
с правильным номером строкиPROFIT!
Не так важна реализация,
главное – идея
128
Можете повторить у себя дома
Ember
Подход №4.2
130
Более простая реализация
github.com/ebryn/ember-component-css
Осторожно – эксперимент!
Ember 2.0
131
Изоляция достигается путем
уникального класса 

на корневом элементе компонента
132
& {	
padding: 2px;	
}	
.foo {	
color: red;	
}
example.hbs example.css
<div class="example-a34fba">	
<span class="foo">	
hello world	
</div>	
</div>
133
.example-a34fba {	
padding: 2px;	
}	
.example-a34fba .foo {	
color: red;	
}
<div class="example-a34fba">	
<span class="foo">	
hello world	
</div>	
</div>
example.hbs example.css
Проблемы
• Пока на уровне прототипа
• Конфликты при вложении компонент
• Нет изоляции включений или стилей
• Под вопросом возможности отладки
134
В самом начале пути, 

но в правильном направлении
135
React
Подход №4.3
137
+ +
React Webpack PostCSS
(local-scope plugin)
tinyurl.com/m9xoefq
138
Изоляция достигается путем
замены имен классов и id

и предоставления карты замен
139
!
Webpack
local-scope
.foo { background: red; }	
#bar { background: green; }
Оригинальный файл стилей
139
!
Webpack
local-scope
.foo { background: red; }	
#bar { background: green; }
Оригинальный файл стилей
139
!
Webpack
local-scope
.foo { background: red; }	
#bar { background: green; }
.ze2420…e8b7 { background: red; }	
#zdf120…a66d { background: green; }
Оригинальный файл стилей
Преобразованный
файл стилей
139
exports.locals = {	
foo: "ze2420…e8b7",	
bar: "zdf120…a66d"	
}
!
Webpack
local-scope
.foo { background: red; }	
#bar { background: green; }
.ze2420…e8b7 { background: red; }	
#zdf120…a66d { background: green; }
Оригинальный файл стилей
Преобразованный
файл стилей
Карта замен
140
loader: 'css?localIdentName=' + (	
process.env.NODE_ENV === 'development' ?	
'[name]__[local]___[hash:base64:5]' :	
'[hash:base64:20]'	
)
Можно управлять видом замены
В режиме разработки:
MyComponent__foo___1rJwx
В боевом окружении:
rJwx92gmbvaLiDdzgXiJ
141
import React from 'react';	
import styles from './MyComponent.css';	
!
class MyComponent extends React.Component {	
render() {	
return (	
<div className={styles.foo}>	
<div className={styles.bar}>	
Local scope!	
</div>	
</div>	
);	
}	
};
Используем оригинальные имена,
не зная их текущего вида
В самом начале пути, 

но в правильном направлении
142
Hot! Появилось всего два месяца назад
Все идет к тому, что это будет
стандартной функцией
загрузчика CSS в Webpack
143
Эпилог
Пока нет идеального способа
изоляции стилей
145
Разработчики браузеров
думают над проблемой
146
Возможно решением будет
Shadow DOM
147
Пока же лучшая альтернатива
пре- и пост-процессинг
148
Надежнее и больше
возможностей
149
Вопросы?
150
Роман Дворнов
@rdvornov
rdvornov@gmail.com
basis.js
basisjs.com
github.com/basisjs

Mais conteúdo relacionado

Mais procurados

Опыт разработки эффективного SPA
Опыт разработки эффективного SPAОпыт разработки эффективного SPA
Опыт разработки эффективного SPAEugene Abrosimov
 
basis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкbasis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкRoman Dvornov
 
Как построить DOM
Как построить DOMКак построить DOM
Как построить DOMRoman Dvornov
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.Igor Shkulipa
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.Igor Shkulipa
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.Igor Shkulipa
 
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014Dmytro Zharii
 
БЭМ в дикой природе
БЭМ в дикой природеБЭМ в дикой природе
БЭМ в дикой природеIhor Zenich
 
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Ontico
 
Пишем БЭМ правильно
Пишем БЭМ правильноПишем БЭМ правильно
Пишем БЭМ правильноIhor Zenich
 
Виталий Харисов "История создания БЭМ. Кратко, сбивчиво и неполно"
Виталий Харисов "История создания БЭМ. Кратко, сбивчиво и неполно"Виталий Харисов "История создания БЭМ. Кратко, сбивчиво и неполно"
Виталий Харисов "История создания БЭМ. Кратко, сбивчиво и неполно"Yandex
 
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfyЧитабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfyDmytro Zharii
 
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)Ontico
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.Igor Shkulipa
 
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDkranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDKrivoy Rog IT Community
 
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)Dmytro Zharii
 
Внутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackВнутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackAlexey Ivanov
 
13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...IT-Portfolio
 

Mais procurados (20)

Опыт разработки эффективного SPA
Опыт разработки эффективного SPAОпыт разработки эффективного SPA
Опыт разработки эффективного SPA
 
basis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворкbasis.js - почему я не бросил разрабатывать свой фреймворк
basis.js - почему я не бросил разрабатывать свой фреймворк
 
Как построить DOM
Как построить DOMКак построить DOM
Как построить DOM
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.
 
Chef @DevWeb
Chef @DevWebChef @DevWeb
Chef @DevWeb
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.
 
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
SWD Page Recorder: Записывает PageObject'ы со скоростью ниндзя SeleniumCamp 2014
 
БЭМ в дикой природе
БЭМ в дикой природеБЭМ в дикой природе
БЭМ в дикой природе
 
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
Радости и гадости регрессионного тестирования вёрстки / Алексей Малейков (HTM...
 
Пишем БЭМ правильно
Пишем БЭМ правильноПишем БЭМ правильно
Пишем БЭМ правильно
 
Виталий Харисов "История создания БЭМ. Кратко, сбивчиво и неполно"
Виталий Харисов "История создания БЭМ. Кратко, сбивчиво и неполно"Виталий Харисов "История создания БЭМ. Кратко, сбивчиво и неполно"
Виталий Харисов "История создания БЭМ. Кратко, сбивчиво и неполно"
 
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfyЧитабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
 
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
Vue.js и его брат-близнец Vue-server.js / Андрей Солодовников (НГС)
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.
 
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDDkranonit S15 Vladimir Melnik - Ruby on Rails, BDD
kranonit S15 Vladimir Melnik - Ruby on Rails, BDD
 
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
Тесты в стиле BDD на C# (Подходы и инструменты; SpecFlow, BDDfy)
 
Внутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpackВнутреннее устройство и оптимизация бандла webpack
Внутреннее устройство и оптимизация бандла webpack
 
13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...
13 октября, DEV {web} - конференция о Highload веб-разработке. "Java под нагр...
 

Destaque

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
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksRoman Dvornov
 
CSSO – история ускорения
CSSO – история ускоренияCSSO – история ускорения
CSSO – история ускоренияRoman Dvornov
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееRoman Dvornov
 
CSSO — минимизируем CSS
 CSSO — минимизируем CSS CSSO — минимизируем CSS
CSSO — минимизируем CSSRoman Dvornov
 
Карточный домик
Карточный домикКарточный домик
Карточный домикRoman Dvornov
 
Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими рукамиRoman Dvornov
 
чувства и эмоции в жизни человека
чувства и эмоции в жизни человекачувства и эмоции в жизни человека
чувства и эмоции в жизни человекаtenshova
 
Технологии продления молодости
Технологии продления молодостиТехнологии продления молодости
Технологии продления молодостиMikhail Kryzhanovskiy
 
Базовые потребности и эмоции человека
Базовые потребности и эмоции человекаБазовые потребности и эмоции человека
Базовые потребности и эмоции человекаSergey Aleksanin
 
Журнал "Про e-learning" #4
Журнал "Про e-learning" #4Журнал "Про e-learning" #4
Журнал "Про e-learning" #4eLearning center
 
психологический портрет личности
психологический портрет личностипсихологический портрет личности
психологический портрет личностиMetOb
 
Проектирование услуг
Проектирование услугПроектирование услуг
Проектирование услугParcsis
 
Управление людьми. Как эмоции влияют на характер? Вадим Нарейко
Управление людьми. Как эмоции влияют на характер? Вадим НарейкоУправление людьми. Как эмоции влияют на характер? Вадим Нарейко
Управление людьми. Как эмоции влияют на характер? Вадим НарейкоVadim Nareyko
 
эмоции человека
эмоции человекаэмоции человека
эмоции человекаaf1311
 
эмоции человека
эмоции человекаэмоции человека
эмоции человекаOlga Demyanova
 
окомистин др
окомистин дрокомистин др
окомистин др1ivanr33
 

Destaque (20)

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)
 
Парсим CSS
Парсим CSSПарсим CSS
Парсим CSS
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricks
 
CSSO – история ускорения
CSSO – история ускоренияCSSO – история ускорения
CSSO – история ускорения
 
Как сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрееКак сделать ваш JavaScript быстрее
Как сделать ваш JavaScript быстрее
 
CSSO — минимизируем CSS
 CSSO — минимизируем CSS CSSO — минимизируем CSS
CSSO — минимизируем CSS
 
Карточный домик
Карточный домикКарточный домик
Карточный домик
 
Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими руками
 
чувства и эмоции в жизни человека
чувства и эмоции в жизни человекачувства и эмоции в жизни человека
чувства и эмоции в жизни человека
 
Технологии продления молодости
Технологии продления молодостиТехнологии продления молодости
Технологии продления молодости
 
Базовые потребности и эмоции человека
Базовые потребности и эмоции человекаБазовые потребности и эмоции человека
Базовые потребности и эмоции человека
 
Журнал "Про e-learning" #4
Журнал "Про e-learning" #4Журнал "Про e-learning" #4
Журнал "Про e-learning" #4
 
психологический портрет личности
психологический портрет личностипсихологический портрет личности
психологический портрет личности
 
Motcsii
MotcsiiMotcsii
Motcsii
 
Проектирование услуг
Проектирование услугПроектирование услуг
Проектирование услуг
 
Управление людьми. Как эмоции влияют на характер? Вадим Нарейко
Управление людьми. Как эмоции влияют на характер? Вадим НарейкоУправление людьми. Как эмоции влияют на характер? Вадим Нарейко
Управление людьми. Как эмоции влияют на характер? Вадим Нарейко
 
эмоции человека
эмоции человекаэмоции человека
эмоции человека
 
эмоции человека
эмоции человекаэмоции человека
эмоции человека
 
окомистин др
окомистин дрокомистин др
окомистин др
 

Semelhante a Жизнь в изоляции

Жизнь в изоляции / Роман Дворнов (Avito)
Жизнь в изоляции / Роман Дворнов (Avito)Жизнь в изоляции / Роман Дворнов (Avito)
Жизнь в изоляции / Роман Дворнов (Avito)Ontico
 
Unit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерUnit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерRoman Dvornov
 
Иван Карев — Клиентская оптимизация
Иван Карев — Клиентская оптимизацияИван Карев — Клиентская оптимизация
Иван Карев — Клиентская оптимизацияYandex
 
Компонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноКомпонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноRoman Dvornov
 
webpack: 7 бед - один ответ
webpack: 7 бед - один ответwebpack: 7 бед - один ответ
webpack: 7 бед - один ответDenis Izmaylov
 
Denis Bugarchev
Denis BugarchevDenis Bugarchev
Denis Bugarchevyaevents
 
Денис Бугарчев "Внедрение идей БЭМ на не-Яндекс проект"
Денис Бугарчев "Внедрение идей БЭМ на не-Яндекс проект"Денис Бугарчев "Внедрение идей БЭМ на не-Яндекс проект"
Денис Бугарчев "Внедрение идей БЭМ на не-Яндекс проект"Yandex
 
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17MoscowJS
 
D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"Dev2Dev
 
Мастер-класс: Разрабатываем сайт с нуля на полном стеке БЭМ-технологий — Жека...
Мастер-класс: Разрабатываем сайт с нуля на полном стеке БЭМ-технологий — Жека...Мастер-класс: Разрабатываем сайт с нуля на полном стеке БЭМ-технологий — Жека...
Мастер-класс: Разрабатываем сайт с нуля на полном стеке БЭМ-технологий — Жека...Yandex
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)Alexander Gornik
 
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)Ontico
 
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruБаба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruYandex
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныCodeFest
 
Александр Даниленко - Panels как философия
Александр Даниленко - Panels как философияАлександр Даниленко - Panels как философия
Александр Даниленко - Panels как философияLEDC 2016
 
Вадим Макишвили "Вёрстка в IntelliJIDEA"
Вадим Макишвили "Вёрстка в IntelliJIDEA"Вадим Макишвили "Вёрстка в IntelliJIDEA"
Вадим Макишвили "Вёрстка в IntelliJIDEA"Yandex
 
JSCS: Разработка архитектуры OpenSource-проектов
JSCS: Разработка архитектуры OpenSource-проектовJSCS: Разработка архитектуры OpenSource-проектов
JSCS: Разработка архитектуры OpenSource-проектовMarat Dulin
 
"Рекомендации по проектированию API" — Марина Степанова, Яндекс
"Рекомендации по проектированию API" — Марина Степанова, Яндекс"Рекомендации по проектированию API" — Марина Степанова, Яндекс
"Рекомендации по проектированию API" — Марина Степанова, ЯндексYandex
 
Презентация: 1С-Bitrix — как начать
Презентация: 1С-Bitrix — как начатьПрезентация: 1С-Bitrix — как начать
Презентация: 1С-Bitrix — как начатьDmitriy Polisadov
 
Масштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаМасштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаRoman Dvornov
 

Semelhante a Жизнь в изоляции (20)

Жизнь в изоляции / Роман Дворнов (Avito)
Жизнь в изоляции / Роман Дворнов (Avito)Жизнь в изоляции / Роман Дворнов (Avito)
Жизнь в изоляции / Роман Дворнов (Avito)
 
Unit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьерUnit-тестирование скриншотами: преодолеваем звуковой барьер
Unit-тестирование скриншотами: преодолеваем звуковой барьер
 
Иван Карев — Клиентская оптимизация
Иван Карев — Клиентская оптимизацияИван Карев — Клиентская оптимизация
Иван Карев — Клиентская оптимизация
 
Компонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективноКомпонентный подход: скучно, неинтересно, бесперспективно
Компонентный подход: скучно, неинтересно, бесперспективно
 
webpack: 7 бед - один ответ
webpack: 7 бед - один ответwebpack: 7 бед - один ответ
webpack: 7 бед - один ответ
 
Denis Bugarchev
Denis BugarchevDenis Bugarchev
Denis Bugarchev
 
Денис Бугарчев "Внедрение идей БЭМ на не-Яндекс проект"
Денис Бугарчев "Внедрение идей БЭМ на не-Яндекс проект"Денис Бугарчев "Внедрение идей БЭМ на не-Яндекс проект"
Денис Бугарчев "Внедрение идей БЭМ на не-Яндекс проект"
 
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
"Webpack: 7 бед — один ответ" — Денис Измайлов, MoscowJS 17
 
D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"D2D Pizza JS Илья Беда "Куда мы все катимся?"
D2D Pizza JS Илья Беда "Куда мы все катимся?"
 
Мастер-класс: Разрабатываем сайт с нуля на полном стеке БЭМ-технологий — Жека...
Мастер-класс: Разрабатываем сайт с нуля на полном стеке БЭМ-технологий — Жека...Мастер-класс: Разрабатываем сайт с нуля на полном стеке БЭМ-технологий — Жека...
Мастер-класс: Разрабатываем сайт с нуля на полном стеке БЭМ-технологий — Жека...
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)
 
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
Как развивать библиотеку компонентов, не ломая ее / Артур Удалов (Mail.Ru Group)
 
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruБаба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
 
Инструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важныИнструменты разные нужны, инструменты разные важны
Инструменты разные нужны, инструменты разные важны
 
Александр Даниленко - Panels как философия
Александр Даниленко - Panels как философияАлександр Даниленко - Panels как философия
Александр Даниленко - Panels как философия
 
Вадим Макишвили "Вёрстка в IntelliJIDEA"
Вадим Макишвили "Вёрстка в IntelliJIDEA"Вадим Макишвили "Вёрстка в IntelliJIDEA"
Вадим Макишвили "Вёрстка в IntelliJIDEA"
 
JSCS: Разработка архитектуры OpenSource-проектов
JSCS: Разработка архитектуры OpenSource-проектовJSCS: Разработка архитектуры OpenSource-проектов
JSCS: Разработка архитектуры OpenSource-проектов
 
"Рекомендации по проектированию API" — Марина Степанова, Яндекс
"Рекомендации по проектированию API" — Марина Степанова, Яндекс"Рекомендации по проектированию API" — Марина Степанова, Яндекс
"Рекомендации по проектированию API" — Марина Степанова, Яндекс
 
Презентация: 1С-Bitrix — как начать
Презентация: 1С-Bitrix — как начатьПрезентация: 1С-Bitrix — как начать
Презентация: 1С-Bitrix — как начать
 
Масштабируемая архитектура фронтенда
Масштабируемая архитектура фронтендаМасштабируемая архитектура фронтенда
Масштабируемая архитектура фронтенда
 

Жизнь в изоляции