react.js: Ускоряем ux/ui

39
@maxmaxmaxmax МАКСИМ КЛИМИШИН CTO GVMachines Inc. React.js: ускоряем UX / UI

Upload: max-klymyshyn

Post on 21-Feb-2017

398 views

Category:

Software


0 download

TRANSCRIPT

@maxmaxmaxmaxМАКСИМ КЛИМИШИНCTO GVMachines Inc.

React.js: ускоряем UX / UI

Обо мне

‣ 12+ лет опыта веб разработки, 6 лет JavaScript, 7 лет Python, год с Clojure

‣ Работал в oDesk (Upwork), Helios, 42CoffeeCups.

‣ Со-организатор конференций PyCon Ukraine, KyivJS, KyivPy, Hotcode

‣ с 2012 года работаю CTO в GVMachines Inc.

GVMachines Inc.

‣ Стартап по доставке продуктов питания из супермаркетов

‣ Работаем в Украине как ZAKAZ.UA (Киев, Днепропетровск, Харьков, скоро в вашем городе) и в США как CartFresh (Бостон)

‣ Python на бекенде

Наш путь

Сегодня поговорим о

Тема

‣ Что у нас было

‣ Почему мы остались с React.js

‣ Как сделать быстрее

‣ Планы

Архитектура

Как это было

Архитектура ПО – это фундаментальные структурные решения, которые будет

несоизмеримо дорого изменить после реализации

Что у нас было

Тема

‣ Python + Django

‣ Solr + специфичные индексы

‣ Redis

‣ jQuery + jQuery UI + bootstrap 2

Как это было

Решили ехать с jQuery и Bootstrap,

не особо заморачиваясь над кодом

Maintainability

Как это было

Поддерживаемость системы – это когда стоимость первоначальной реализации существенно больше в сравнении со

стоимостью изменений

Как это было

‣ Кода ставало больше, менять было сложнее.

‣ Корзина генерилась в iframe огромным куском Django-шаблона. Работать было крайне сложно.

‣ Страница продукта – сложный микс контекста для шаблона, шаблона и нескольких js файлов

‣ JS код в перемешку с Django Templates

‣ Фикс одной ошибки порождал две новые

Решение

Стратегия

Разработка

‣ Опробовать новые технологии: Angular, Backbone, React.js

‣ Внедрять постепенно, не ломая по дороге и не переписывая весь проект

‣ Интеграционные тесты

Результат

Разработка

‣ Angular отпал сразу как слишком сложный

‣ Backbone.js был, но на тот момент у него были проблемы с утечкой памяти и никакого преимущества по сравнению с jQuery кодом не было

Разработка

React.js прижился, посколько ощутимо выигрывал в производительности перед фреймворками, при этом не требовал слишком глубоко знания инструмента

Разработка

Ключевые преимущества‣ Если прегенерировать код на сервере – реакт не будет этого делать на клиенте

‣ Для генерации достаточно подать одинаковое состояние

‣ Если состояние между генерацией и отображением изменится – реакт произведет минимальное количество изменений DOM

РезультатРазработка

Короче, мы купились на то, как команда React.js превратили O(n3) проблему в O(n) с помощью двух простых допущений

Процесс

Планируем

Процесс

‣ Переход плавный, для начала переписываем самую ключевую часть – корзину

‣ Решили обойтись без common.js и т.п. –не все члены команды понимали как это работает

Планируем

Процесс

‣ Серверный рендеринг – второй этап

‣ Перевод каталога – третий этап

‣ Перевод взаимодействия с пользователем – четвертый этап

Все как обычно

Процесс

‣ После корзины 2 года мы шли к каталогу

‣ Серверный рендеринг реализован несколько месяцев после полноценной работы каталога

Разница в перспективе

Процесс

‣ По ходу знакомство с новыми концепциями: CSP, Immutable DS, Clojure, CRDT, Haskell

‣ Теория очередей, практическая работа по моделированию

Процесс

‣ Вторая итерация затянулась с аутсорсом

‣ Привычка генерировать состояние server-side добавила геморроя

‣ Изменения вынудили написать новый бекенд для API

Плохие решения

Процесс

‣ Строить новую систему максимально используя старый бекенд привело к нереальному усложнению кода бекенда

‣ Использовать подход с $.ajax внутри React.js компонент привело к усложнению и copy-paste-style коду на клиенте

Плохие решения

Процесс

‣ Продолжить использование глобальных переменных

‣ Продолжить использовать глобальные события

Детали

Унифицированный API

Детали

‣ Решение вынести сложность по генерации состояния в API с возможностью композиции и аггрегации

‣ Один API для всех – Mobile app, website front-end

Унифицированный API

Детали

‣ Решение вынести сложность по генерации состояния в API с возможностью композиции и аггрегации

‣ API использует как бекенд так и клиент

‣ Избавило от необходимости отдавать сайт через node.js сервер

Side-effects

Детали

‣ Параллельные запросы в одном API вызове

‣ Простые и понятные ошибки валидации аргументов

‣ Генерация документации на базе простой интроспекции API вызовов

Пример запроса

Детали

{ "meta": {"session_id": “%SESSION_ID”}, "request": [ { "type": "timewindows.list", "args": { "store_ids": ["00002111"], "zone_id": "02111" }, "v": "0.1" } ] }

Пример доки

Детали

MODULE: timewindows-------------------------------------------RESOURCE: timewindows.list{'count': <Or(<Int(gt=0)>, <Null>)>, 'index': <class 'trafaret.Int'>, 'only_available': <class 'trafaret.Bool'>, 'store_ids': <List(<String>)>, 'zone_id': <String>}

Архитектура

API SERVERS

request state

generated state response

RENDERING WORKER

REACT.JS DOM RENDERER

put html into cache

CACHE SERVERS

time

Что дальше?

Планы

‣ детерминированная модель для инвалидации сгенерированного дома дерева

‣ Уменьшение количества асинхронного кода в JS (CSP)

‣ Неизменяемые структуры (Redux, Immutable)

‣ Работа с корзиной через CRDT-базу

Планы

static state (state, channel, n=0) { // we could use CSP channels here return go(function * () { yield put(channel, title(“About"));

var talks = yield take(json({url: “/api/talks.json”}));

yield put(channel, [“talks", talks]);

channel.close() }) }

Communicating sequential processes

Планы

CRDT (Swarm.js)

Спасибо.

Thanks!

@maxmaxmaxmax