29
Эволюция клиентской разработки: от веба ко «всеобщей мобилизации» или mobile-first на примере Badoo Павел Довбуш

Эволюция клиентской разработки: от веба ко "всеобщей мобилизации"

Embed Size (px)

Citation preview

Эволюция клиентской разработки: от веба ко «всеобщей мобилизации»

или mobile-first на примере Badoo

Павел Довбуш

«Простой» веб

● 1 платформа, 0 ⇒ 50 М пользователей● Логика отображения и шаблонизация на сервере● HTML по сети● Переход между страницами - полная перерисовка● JavaScript - “Ajax и украшения”

«Простой» Веб с точки зрения разработки

● Параллельная разработка● Договоренности “как делать”, простая “интеграция”● Узкая специализация● Хорошо работает при небольшом количестве

человек

Рост + появление мобильных

● Усложнение дизайна и верстки● Все больше интерактива● Больше пользователей, новые рынки

Мобильные:● Эксперементальная команда● Малая доля трафика, еще меньшая - дохода● Учимся взаимодействовать с несколькими

платформами

Веб 1.5

● Нужно улучшить user experience● Делаем одностраничное приложение● Что переносить на клиент?

○ переводим на API○ или половинчатое решение

Переход Web 1.0 ⇒ 1.5

Переход Web 1.0 ⇒ 1.5

● Логика отображения и шаблонизация на сервере● JSON + HTML по сети● Переход между страницами - перерисовка

фрагментов● JavaScript - приложение, частично логика

Web 1.5 – Результаты

● Для пользователя:○ ускорение в ~3 раза○ kpi ~1 секунда

● Переход ~2 месяца 80% функционала, “хвост” доделок

● Изменили 20% кода● Та же структура команд и разработки

Jinba

● Рождение Jinba - нашей системы аналитики и мониторинга UX

● Доклад RIT/2015: Реалтайм статистика скорости работы нативных и веб-приложений у реальных пользователейhttps://goo.gl/NARWL1

Мобильные клиенты

● Мобильный трафик растет● Стабилизировался протокол● Стандарты и подходы работы между

мобильными командами

Мобильный веб

● Отдельная команда● Сначала для feature-phone, потом HTML5● REST+JSON прокси● Стандартные фреймворки и решения

Рост + превалирование мобильных

● Сайт - Усложнение дизайна и верстки● Сайт - Все больше интерактива, анимаций,

усложнение логики● Больше мобильного трафика● Рост команд и компании● Распространение Jinba на все платформы

(доклад РИТ 2015 - https://goo.gl/NARWL1)

Протокол

Точка синхронизации между платформами

● Своя надстройка над Google Protocol Buffers● Строгая типизация и валидация● Сообщения и команды - описание в одном месте● Генерация “реализации” для всех платформ● Версионирование сообщений и полей а не API● Поддержка десятков версий приложений

Мобильный Веб ⇒ mAPI

● Так ли нужен МобайлВеб прокси?○ фиксит протокол○ Protobuf RPC ⇒ REST+JSON○ немного логики

Переход:● Генерация JS классов для сообщений● Высокоуровневая абстракция RPC● Подробности - доклад

JSConf EU 2014 - http://goo.gl/8AvRgU

Веб 1.5 ⇒ mAPI

● Делаем по два раза● Усложнение контроля в связи

с ростом команд● Высокая связность мешает развитию● Мобильный трафик больше десктопного

Веб 1.5 ⇒ mAPI

Задача:● Сделать Веб таким же клиентом как мобильные ● Упростить структуру разработки● Делать функционал один раз, использовать везде● Перевести фокус на мобильные клиенты

Решение:● ~1 год работы, изменение структуры разработки● Повезло - совместили с редизайном● Сближение с мобильными по функционалу

mAPI команда

● Протокол - язык общения между командами● Отдельная команда ответственная за протокол● Документирование изменений на всех

платформах● Центр - не только технически, но и по процессам

Итого

● Протокол - язык общения между командами● Первой реализовать фичу может любая

клиентская команда● Перераспределение разработчиков

○ Бэкенд○ QA○ Веб ⇔ Мобайл Веб

● Унификация технологий● Унификация процесса разработки

Вопросы?

Павел Довбуш[email protected]

Протокол

enum Role {ADMIN = 1;USER = 2;

}

message User {required string name = 1;optional uint32 age = 2;required Role role = 3;

}

Interface description language

var Role = new GpbEnum();Role._values = [ 1, 2 ];Role.ADMIN = 1;Role.USER = 2;

class User extends GpbMessage {getName() { … }setName() { … }hasName() { … }getAge() { … }getRole() { … }

}

var user = new User().setName(‘John’).setAge(30).setRole(Role.USER);

Генарация классов

new RPC(request_type, parameter) .on(response_type, callback) .on([type1, type2], callback) .request();

Обмен сообщениями (двусторонний RPC)

RPC.any.on(type3, callback);

request_type & response_type значения enum MessageTypeparameter & response сообщения Protobuf

function callback(err, /** Type1 */ response1) { }

Message exchange

new Rpc(MT.SERVER_GET_USER_LIST, new ServerGetUserList()

.setFolderId(FolderTypes.FRIENDS)).on(MT.CLIENT_USER_LIST, onClientUserList).request();

function onClientUserList(err, clientUserList) {var users = clientUserList.getUsers();users[0].getName();

}

Обмен сообщениями (двусторонний RPC)

Message exchange