45
Изоморфная разработка c React.js @maxmaxmaxmax МАКСИМ КЛИМИШИН CTO ZAKAZ.UA GVMachines Inc.

Изоформные приложения на React.js

Embed Size (px)

Citation preview

Page 1: Изоформные приложения на React.js

Изоморфная разработка c React.js

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

Page 2: Изоформные приложения на React.js

Что такое изоморфный код?

isomorphic

Page 3: Изоформные приложения на React.js

Возможность использовать один и тот же код

как на клиенте так и на сервере

ISOMORPHIC

Page 4: Изоформные приложения на React.js

СЕЙЧАС

CLIENT

API

SERVER

изоморфный код

Page 5: Изоформные приложения на React.js

Value proposition

Page 6: Изоформные приложения на React.js

Проблемы one page apps

Зачем это надо?

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

‣ Тяжелая операция по рендерингу и созданию DOM-дерева

‣ Недружелюбные для краулеров (hashbang)

Page 7: Изоформные приложения на React.js

Проблемы архитектуры

Зачем это надо?

‣ Двойная валидация входных данных

‣ Поддержка сложной бизнес-логики одновременно на клиенте и на сервере

‣ Зависимость от сервера в мобильных приложениях

Page 8: Изоформные приложения на React.js

Изоморфный JavaScript может

решить эти проблемы

Зачем это надо?

Page 9: Изоформные приложения на React.js

CSP Channels Communicating sequential processes

Page 10: Изоформные приложения на React.js

‣ Параллельные процессы обмениваются информацией

‣ Безбуферный обмен информацией типа «рандеву»

‣ Взаимодействие происходит через канал

CSP channels

Page 11: Изоформные приложения на React.js

var ch = chan();

go(function*() { yield put(ch, 1); console.log(2); yield put(ch, 3); console.log(yield take(ch)); });

go(function*() { console.log(yield take(ch)); //yield timeout(100); console.log(4); console.log(yield take(ch)); yield put(ch, 5); });

Пример

1 4 2 3 5

Результат

Page 12: Изоформные приложения на React.js

CSP

Page 13: Изоформные приложения на React.js

React.js

Page 14: Изоформные приложения на React.js

Что нужно

‣ Рендерить компоненты на сервере

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

‣ Максимально унифицировать код сервера и клиента

Page 15: Изоформные приложения на React.js

Состояние запроса

‣ Location

‣ Cookies

‣ GET params

‣ POST params

request = url + cookies + get + post

Page 16: Изоформные приложения на React.js

Пример{ client: (location) => { return state.merge(Map([ ["url", location.pathname], ["protocol", location.protocol], ["hostname", location.hostname], ["hash", location.hash] ])); }, server: (request) => { return state.merge(Map([ ["url", request.url], ["method", request.method] ])); } }

Page 17: Изоформные приложения на React.js

Состояние приложения

‣ API/external source call 1,

‣ Call 2

‣ Call i

state = f(request)

Page 18: Изоформные приложения на React.js

Архитектурно

REQUEST STATE APPBROWSER

API

RES

PON

SE

ISO

MO

RPH

IC R

END

ER

APP

Page 19: Изоформные приложения на React.js

Архитектурно

state = f(request) dom_cli = React.render(…state) html_srv = React.renderToString(…state)

Page 20: Изоформные приложения на React.js

Примерmodule.exports = React.createClass({ statics: { // state will be executed within CSP `go` routine state: function(state, channel) { return go(function * () { yield put(channel, ["title", "World"]); channel.close(); }) } }, render: function () { return <h1>Hello, <span>{this.props.title}</span></h1> }})

Page 21: Изоформные приложения на React.js

Примерvar stateCh = chan(), component = React.createFactory(type); type.state ? type.state(state, stateCh) : null; go(function *() { var context = Map(yield take(stateCh)); yield put(renderCh, Map([ … [keys.state, context], [keys.render, {server: server(component), client: client(component)}] ]))});

Page 22: Изоформные приложения на React.js

Примерvar client = (component) => { return (context) => { return React.render( component(context.get(keys.state).toObject()), document.getElementById(context.get(keys.name))); }}; var server = (component) => { return (context) => { return React.renderToString( component(context.get(keys.state).toObject())); }};

Page 23: Изоформные приложения на React.js

isoroutes

Попробовать можно

https://goo.gl/xyptPx

Page 24: Изоформные приложения на React.js

Как это сделать в React.js

‣ в root-овом компоненте определить статический изоморфный метод, который

‣ собирает состояние запроса: path, cookies get params, post params

‣ консолидирует забор данных

‣ отложить рендер root-ового компонента до конца выполнения метода

Page 25: Изоформные приложения на React.js

Решения

‣ Relay – анализ запросов, cache engine

‣ GraphQL – консолидирует сложность API

‣ Transmit – очень тупая query engine, которая делегируется на код query

Page 26: Изоформные приложения на React.js

Relay

Relay.createContainer(Story, { queries: { story: graphql` Story { author { name, profile_picture { uri } }, text}` }

Page 27: Изоформные приложения на React.js

Недостатки

‣ Relay – нет релиза

‣ GraphQL – нет релиза, но есть парсер

Page 28: Изоформные приложения на React.js

Transmit.createContainer(Main, { queryParams: { pagesToFetch: 10 }, queries: { /** * Return a Promise */ data: function (queryParams) { // isomorphic fetch return fetch(…).then(…) } }

Transmitзамена relay+graphql на промисы

Page 29: Изоформные приложения на React.js

Transmit

Попробовать можно в google://react-isomorphic-starterkit

Page 30: Изоформные приложения на React.js

64К результатов isomorphic react.js

против 47M react.js

Page 31: Изоформные приложения на React.js

React Native теперь можно создавать мобильные приложения

МОБИЛЬНЫЕ

Page 32: Изоформные приложения на React.js

Реакт доставляэ.

Page 33: Изоформные приложения на React.js

REACT NATIVE

CLI

ENT

SERV

ERизоморфный код

API

MOBILE

Page 34: Изоформные приложения на React.js

Изоморфный JS как отдельный сервис

Page 35: Изоформные приложения на React.js

Service

‣ Асинхронная загрузка данных располагает к медленному бекенду

‣ Тупое кеширование приводит к сложной инвалидации

Проблемс

Page 36: Изоформные приложения на React.js

А почему-бы не сделать отдельный сервис, который рендерит JavaScript где надо

Service

Page 37: Изоформные приложения на React.js

Service

‣ Синхронный сервис

‣ Очередь задач, асинхронно

Два варианта

Page 38: Изоформные приложения на React.js

Service

приложение

database cache node.js

Page 39: Изоформные приложения на React.js

rendered rendered

task 1

запрос 2

state

сервер задач node.js

запрос 1

state

task 2

cache

Page 40: Изоформные приложения на React.js

Полезно для мозга

Page 41: Изоформные приложения на React.js

Выводы

Page 42: Изоформные приложения на React.js

Выводы

‣ Увеличивается количество shared кода, уменьшается рассеивание бизнес логики между разными платформами (клиент, сервер, мобильные)

‣ Улучшается UX – за счет пререндеринга пользователь получает картинку на экране быстрее

‣ Улучшается видимость в поисковых системах

‣ Не нужно все переписывать на JavaScript

Page 43: Изоформные приложения на React.js

Недостатки

‣ Ограничения всех платформ, учавствующих в выполнении приложения (клиент ∩ сервер ∩ мобильный)

‣ Увеличивает количество компонентов в системе (если не node.js-based проект)

‣ Сложнее тестировать

Page 44: Изоформные приложения на React.js

Кто в темеВыводы

‣ Facebook

‣ Instagram

‣ Yahoo! Mail

‣ Walmart

‣ Airbnb

‣ Netflix

Page 45: Изоформные приложения на React.js

@maxmaxmaxmax