Маcштабируемая архитектура
фронтенда
Роман Дворнов
Москва, 2018
Работаю в Avito
Open source:

basis.js, CSSO, 

component-inspector, 

csstree, rempl и другие
github.com/lahmatiy
twitter.com/rdvornov
rdvornov@gmail.com
Контекст
Avito – несколько сайтов и SPA
5
HTML
JavaScript
(генерирует HTML/DOM)
Сервер
Клиент
Сайт SPA
Обязательно
vs.
5
HTML
JavaScript
(интерактивность)
JavaScript
(генерирует HTML/DOM)
Сервер
Клиент
Сайт SPA
Обязательно
Опционально
vs.
5
HTML
JavaScript
(интерактивность)
JavaScript
(генерирует HTML/DOM)
SSRСервер
Клиент
Сайт SPA
Обязательно
Опционально
vs.
Разница между 

сайтом и SPA в том, что...
6
Разница между 

сайтом и SPA в том, что...
6
🤔
Когда все просто
7
Feature 1 Feature 2 Feature N...
ProjectTeam
Когда все сложно
8
Feature 1 Feature 2 Feature N...
Project 1
Project 2
...
Project N
Когда все сложно
8
Feature 1 Feature 2 Feature N...
Project 1
Project 2
...
Project N
Team
Team
Team
Когда все сложно
8
Feature 1 Feature 2 Feature N...
Project 1
Project 2
...
Project N
Team Team Team
«Проект»

сайт/SPA, страница, приложение (mobile)
9
В чем разница
• Проект-команда
• Плохая предсказуемость доставки фичи,
сложно приоритезировать, разное понимание
• Фича-команда
• Много разных интеграций, но хорошая
предсказуемость и проработка фич
10
В чем разница
• Проект-команда
• Плохая предсказуемость доставки фичи,
сложно приоритезировать, разное понимание
• Фича-команда
• Много разных интеграций, но хорошая
предсказуемость и проработка фич
10
Было
Сейчас
Команда 1
Команда 2
Команда 3
Команда 4
Команда 5
Проблемы больших продуктов
• Больше «проектов» – больше точек интеграции
• Увеличивается число команд с одной кодовой
базой
• Постоянно усложняется (новые фичи)
• Растет кодовая база и техдолг (легаси)
• ...
12
Как будем лечить
• Экосистема страниц
• Организация процессов разработки
• Платформа
13
Экосистема страницы
Экосистема страницы
задает окружение для компонент/блоков,
избавляя от решения типовых задач
15
Типовые задачи
• Лейаут страницы
• Управление слоями
• Загрузка и управление зависимостями
• Источники данных (модели, нотификация)
• Персистентное хранение данных
• Транспорт
• Роутинг
• и т.д.
16
Core
Layout
Slot 1 Slot 2 Slot N
...
Core
Layout
Slot 1 Slot 2 Slot N
...
Core
Block 1 Block 2 Block N
Layout
Slot 1 Slot 2 Slot N
...
Core
Block 1 Block 2 Block N
...Plugin 1 Plugin 2 Plugin N
Layout
Slot 1 Slot 2 Slot N
...
Core
Block 1 Block 2 Block N
...Plugin 1 Plugin 2 Plugin N
Common Public API
Layout
Slot 1 Slot 2 Slot N
...
Core
Block 1 Block 2 Block N
Plugin Method 1 Plugin Method 2 ...
...Plugin 1 Plugin 2 Plugin N
Common Public API
Layout
Slot 1 Slot 2 Slot N
...
Core
Block 1 Block 2 Block N
Plugin Method 1 Plugin Method 2 ...
Browser API
...Plugin 1 Plugin 2 Plugin N
Common Public API
Layout
Slot 1 Slot 2 Slot N
...
Page Ecosystem
Core
Block 1 Block 2 Block N
Plugin Method 1 Plugin Method 2 ...
Browser API
...Plugin 1 Plugin 2 Plugin N
Common Public API
Абстракция от окружения
Блоки не используют браузерное API, 

а используют API ядра и его плагинов
19
Block 1
Block 2
Server
Block 1
Block 2
Server
GET /what/ever
Block 1
Block 2
Server
GET /what/ever
GET /what/ever
Block 1
Block 2
Server
Common
Public
API
Block 1
Block 2
Server
Common
Public
API
getWhatEver()
Block 1
Block 2
Server
Common
Public
API
getWhatEver()
getWhatEver()
Block 1
Block 2
Server
Common
Public
API
getWhatEver()
getWhatEver()
request
Block 1
Block 2
Server
Common
Public
API
getWhatEver()
getWhatEver()
request
Но это не точно
Экосистема – черный ящик
22
Что может быть
• Запрос к серверу
• Данные из кеша
• Синхронизация между закладками
• SSE/WebSocket/ServiceWorker/etc
• ...
23
Что может быть
• Запрос к серверу
• Данные из кеша
• Синхронизация между закладками
• SSE/WebSocket/ServiceWorker/etc
• ...
23
Progressive
enhancement
Реализация экосистемы может ...
• Меняться (подходы и технологии)
• Различаться от проекта к проекту
• Совершенствоваться со временем
• ...
• Блокам/компонентам все равно
24
Плюшки
• Стенд для разработки блока
• Моки без костылей
• Реализации под «среду»
• браузер
• серверный рендеринг
• тесты
25
Общее публичное API
Common Public API
Общая кросс-проектная
структура API
27
Зачем?
• Переиспользование блоков без адаптации к API
• Используем подходящую реализацию ядра, в
зависимости от среды
• Проще новые интеграции (меньше учить)
28
Модульность
«Нет» монолитам!
• Подключение (с динамической подгрузкой)
дополнительной функциональности в ядро по
принципу плагинов
• Интерфейсы декомпозируются на логические
блоки, с динамической подгрузкой (включая
зависимости) и обновлением
30
Подход подразумевает
• Функциональность (API) экосистемы расширяется
(догружается) по мере потребностей блоков
• Разные версии одних и тех же зависимостей в
рамках одного окружения (страницы)
• Блоки взаимодействуют только с публичным API
• Креш блока не тянет за собой все остальное
31
Точки отказа
• Ядро – единственная критическая часть,
ничего не будет работать
• Плагин ядра – не будут работать плагины и
блоки, которые от него зависят
• Блок – проблемы блока никого не касаются
32
Итоги
Экосистема страницы
• Абстракция от окружения
• Общее публичное API
• Модульность
34
Управление разработкой
Порядок и комфорт
• Владение кодом
• Независимость команд
• Контроль зависимостей и версий
• Инкрементальные рефакторинг и миграция
36
Владение кодом
Общее – значит ничье
38
У каждого «компонента» системы должен
быть определен единственный владелец
39
Компонент это
• Репозиторий
• Директория или файл (модуль)
• npm-пакет
• Страница
• Чанк
• ...
40
Информация хранится 

в базе знаний (реестре)
41
Пример
42
Action plan
• Проблема, баг или вопрос?
• Определяется релевантный компонент, 

с которым это связано и его владелец
• Направляется запрос владельцу
• Владелец решает вопрос сам или переадресует
другим, но контролирует его разрешение
43
Независимость команд
Команды минимизируют взаимодействие
между собой при реализации фич,
исправлении багов и релизах
45
Независимость команд
• Модульность: блоки (функциональность)
изолируются в пакеты
• Могут использовать собственную версию
зависимости, апгрейдится в удобное время
• Поддержка более мягких интеграций
• Автоматизация тестирования
46
Типы интеграции
• Жесткая интеграция – изменения кода компонента
(требуется публикация пакета, пересборка и релиз
зависимых модулей и проектов)
• Конфигурационная интеграция – изменение
конфигурации экземпляра компонента (требуется
пересборка и релиз модуля и проекта)
• Мета интеграция – конфигурация блока описывается и
хранится вне кода (не требует пересборки и релиза)
47
Управление зависимостями и
версиями
Чтобы избежать Dependency hell –
регулярный сбор и анализ зависимостей
49
Статический анализ

package.json и кода
50
Версии (первый подход)
51
Использование UI компонент
52
Инкрементальный рефакторинг
Нельзя так просто взять и все зарефакторить
Возможность производить рефакторинг
или миграцию на новые решения и
технологии поэтапно
55
Инкрементальный рефакторинг
• Возможность не делать все сразу
• Рефакторинг не больше недели → релиз
• Толерантность к легаси – старое должно
продолжать работать без приложения усилий
(консервация до лучших времен)
56
Мы сейчас все запилим с нуля и
все станет хорошо
57
Мы сейчас все запилим с нуля и
все станет хорошо
57
Итоги
Управление разработкой
• Владение кодом
• Независимость команд
• Управление зависимостями и версиями
• Инкрементальный рефакторинг
59
Платформа
Платформа – рекомендованный набор
технических решений в компании
61
Дизайн система
Общие подходы к разработке интерфейсов, 

готовые UI компоненты и инструментарий
63
Дизайн система
• UI Kit (для дизайнеров)
• UI компоненты (для разработчиков)
• Каталог UI компонент
• Общие паттерны и решения
• ...
64
Ограниченный технологический
стек
Меньше зоопарк технологий –
дешевле делать общие решения
67
Tech Radar
68
Build Your Own
Technology Radar
Подробнее в статье:
Инфраструктура
Инфраструктура
• Сборка проектов
• Управление зависимостями, публикациями и версиями
• Организация тестирования (настройка, инструменты, хелперы etc)
• Репортинг (ошибки, performance, etc), мониторинг, Health Check
• База знаний
• Скрипты по сбору данных (анализ кода, тегирование, etc)
• ...
70
Модульность → репы и пакеты →
затраты на поддержку
71
По моему скромному опыту:
настроить проект с нуля, имея опыт, 

занимает несколько часов, не считая поддержки
72
Инфраструктура – не всегда готовое
• Unit-тестирование скриншотами: преодолеваем
звуковой барьер – Роман Дворнов

видео, расшифровка
• Скриншоты как сервис – Сергей Мелюков

видео
73
Идеальная настройка
74
{
...
"dependencies": {
"@avito/platform": "latest",
...
}
}
package.json
Итоги
Платформа
• Дизайн система
• Ограниченный технологический стек
• Инфраструктура
76
Заключение
Если вам показалось, 

что все просто и логично –
отлично, так и задумано!
78
не верьте мне на слово 😉
79
Не все еще проверено в реальных условиях
не верьте мне на слово 😉
79
Не все еще проверено в реальных условиях
Ожидайте update через полгода
Роман Дворнов
@rdvornov
rdvornov@gmail.com
Спасибо!

Масштабируемая архитектура фронтенда