Изоморфная разработка
c React.js
@maxmaxmaxmaxМАКСИМ КЛИМИШИН
CTO ZAKAZ.UA
GVMachines Inc.
Что такое
изоморфный код?
isomorphic
Возможностьиспользовать
одини тотжекод
какнаклиентетакинасервере
ISOMORPHIC
СЕЙЧАС
CLIENT
API
SERVER
изоморфный код
Valueproposition
Проблемыonepageapps
Зачем это надо?
‣ Производительность-загрузкаданных,
задержкаотображенияпристарте
‣ Тяжелаяоперацияпорендерингуисозданию
DOM-дерева
‣ Недружелюбныедлякраулеров(hashbang)
Проблемыархитектуры
Зачем это надо?
‣ Двойнаявалидациявходныхданных
‣ Поддержкасложнойбизнес-логики
одновременнонаклиентеинасервере
‣ Зависимость отсерверавмобильных
приложениях
ИзоморфныйJavaScript
может
решитьэти проблемы
Зачем это надо?
CSPChannels
Communicating sequentialprocesses
‣ Параллельныепроцессыобмениваются
информацией
‣ Безбуферныйобменинформациейтипа
«рандеву»
‣ Взаимодействиепроисходитчерезканал
CSPchannels
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
Результат
CSP
React.js
Чтонужно
‣ Рендеритькомпонентына сервере
‣ Обновлятьданныенаклиенте без
перезагрузкистраницы
‣ Максимальноунифицироватькодсервераи
клиента
Состояниезапроса
‣ Location
‣ Cookies
‣ GETparams
‣ POSTparams
request = url + cookies + get + post
Пример
{
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]
]));
}
}
Состояниеприложения
‣ API/external sourcecall1,
‣ Call2
‣ Calli
state = f(request)
Архитектурно
REQUEST STATE APPBROWSER
APIRESPONSE
ISOMORPHICRENDER
APP
Архитектурно
state = f(request)
dom_cli = React.render(…state)
html_srv = React.renderToString(…state)
Пример
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>
}})
Пример
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)}]
]))});
Пример
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()));
}};
isoroutes
Попробоватьможно
https://goo.gl/xyptPx
КакэтосделатьвReact.js
‣ вroot-овомкомпонентеопределить
статическийизоморфныйметод,который
‣ собираетсостояниезапроса:path,cookies
getparams,postparams
‣ консолидируетзаборданных
‣ отложитьрендерroot-овогокомпонентадо
концавыполненияметода
Решения
‣ Relay–анализзапросов,cache engine
‣ GraphQL– консолидируетсложность API
‣ Transmit– оченьтупая queryengine,которая
делегируетсянакодquery
Relay
Relay.createContainer(Story, {
queries: {
story: graphql`
Story {
author {
name,
profile_picture {
uri
}
},
text}`
}
Недостатки
‣ Relay– нетрелиза
‣ GraphQL– нет релиза,ноестьпарсер
Transmit.createContainer(Main, {
queryParams: {
pagesToFetch: 10
},
queries: {
/**
* Return a Promise */
data: function (queryParams) {
// isomorphic fetch
return fetch(…).then(…)
}
}
Transmit
заменаrelay+graphqlнапромисы
Transmit
Попробоватьможнов
google://react-isomorphic-starterkit
64Крезультатовisomorphicreact.js
против 47Mreact.js
React Native
теперьможносоздавать
мобильныеприложения
МОБИЛЬНЫЕ
Реактдоставляэ.
REACT NATIVE
CLIENT
SERVER
изоморфный код
API
MOBILE
Изоморфный JSкак
отдельныйсервис
Service
‣ Асинхронная загрузкаданныхрасполагаетк
медленномубекенду
‣ Тупоекешированиеприводитксложной
инвалидации
Проблемс
Апочему-быне сделать
отдельныйсервис,который
рендеритJavaScriptгденадо
Service
Service
‣ Синхронныйсервис
‣ Очередь задач,асинхронно
Дваварианта
Service
приложение
database cache node.js
rendered rendered
task1
запрос2
state
серверзадачnode.js
запрос1
state
task2
cache
Полезнодлямозга
Выводы
Выводы
‣ Увеличиваетсяколичествоsharedкода,
уменьшаетсярассеивание бизнеслогики
междуразнымиплатформами(клиент,сервер,
мобильные)
‣ УлучшаетсяUX– засчет пререндеринга
пользовательполучаеткартинкунаэкране
быстрее
‣ Улучшаетсявидимостьвпоисковыхсистемах
‣ НенужновсепереписыватьнаJavaScript
Недостатки
‣ Ограничениявсехплатформ,учавствующихв
выполненииприложения (клиент∩сервер∩
мобильный)
‣ Увеличиваетколичествокомпонентовв
системе(если неnode.js-basedпроект)
‣ Сложнеетестировать
Ктовтеме
Выводы
‣ Facebook
‣ Instagram
‣ Yahoo!Mail
‣ Walmart
‣ Airbnb
‣ Netflix
@maxmaxmaxmax

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