Изоморфные react-приложения

115
Изоморфные React-приложения Денис Измайлов 23 ноября 2015

Transcript of Изоморфные react-приложения

Page 1: Изоморфные react-приложения

ИзоморфныеReact-приложенияДенис Измайлов

23 ноября 2015

Page 2: Изоморфные react-приложения

Денис Измайлов• 15 лет опыта разработки ПО и web

• Последние 5 лет полностью Front-end, Node.js и архитектуре

• Более 10 проектов, в т.ч. много SPA, highload и React

• Коммиты в Redux, webpack и koa

• Спикер HighLoad++ 2015, MoscowJS

• Автор статей на Habrahabr и англоязычных ресурсах

, CEO

Page 3: Изоморфные react-приложения

Почему от классического Single Page Application необходимо отказаться?

Page 4: Изоморфные react-приложения

Как изоморфные приложения отразятся на Вашей зарплате?

Page 5: Изоморфные react-приложения

Что вы будете делатьна этих выходных?

Page 6: Изоморфные react-приложения

Вы уже знаете1. React 14

2. webpack

3. ES6

4. Node.js

5. Express / koa

6. Isomorphic (Universal) apps6

Page 7: Изоморфные react-приложения

Часть 1

Page 8: Изоморфные react-приложения

Web стал очень большим

Page 9: Изоморфные react-приложения

Искусство

Разработка под Web

Наука

Page 10: Изоморфные react-приложения

Раньше было просто• Создал страницу

• Добавил пару скриптов

• Отправил в Production

Page 11: Изоморфные react-приложения

Раньше было просто

Сервер

Браузер

11

Page 12: Изоморфные react-приложения

Раньше было просто

Сервер

Браузер

Делал всё

12

Page 13: Изоморфные react-приложения

Раньше было просто

Сервер

Браузер- HTML - [CSS, JavaScript]

Делал всё

13

Page 14: Изоморфные react-приложения

Это работало

Page 15: Изоморфные react-приложения

Single PageApplications

(SPA)

Page 16: Изоморфные react-приложения

Single Page Application

Сервер

Браузер

16

Page 17: Изоморфные react-приложения

Single Page Application

Сервер

Браузер

Страница существует?Авторизация нужна? Доступ есть?

17

Page 18: Изоморфные react-приложения

Single Page Application

Сервер

Браузер

Страница существует?Авторизация нужна? Доступ есть?

- Tiny HTML, [CSS] - JavaScript bundle

18

Page 19: Изоморфные react-приложения

Single Page ApplicationПлюсы

• Легко начать • webpack

• <div id=“root” />

• React, Redux

• build

19

Page 20: Изоморфные react-приложения

Single Page ApplicationПлюсы

• Легко начать

• Богатый функционал

webpack, <div id=“root” />, React, Redux

20

Page 21: Изоморфные react-приложения

Single Page ApplicationПлюсы

• Легко начать

• Богатый функционал

• Быстро дорабатывать

webpack, <div id=“root” />, React, Redux

21

Page 22: Изоморфные react-приложения

Single Page ApplicationПлюсы

• Легко начать

• Богатый функционал

• Быстро дорабатывать

• Отзывчивый UI

webpack, <div id=“root” />, React, Redux

22

Page 23: Изоморфные react-приложения

Single Page ApplicationПлюсы

• Легко начать

• Богатый функционал

• Быстро дорабатывать

• Отзывчивый UI

• Удобно кэшировать

webpack, <div id=“root” />, React, Redux

23

Page 24: Изоморфные react-приложения

- Wow. И не одного минуса?

Page 25: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка • JavaScript bundle up to 3-5 Mb

• первое обращение

• исполнение

• память

25

Page 26: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

• Сложность поддержки

• side-эффекты

• memory leak

1st request, CPU, mem

26

Page 27: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

• Сложность поддержки

• Пустая страница, один URL

1st request, CPU, mem

side-эффекты, memory leaks

27

Page 28: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

• Сложность поддержки

• Пустая страница, один URL

• Legacy Browsers

1st request, CPU, mem

side-эффекты, memory leaks

28

Page 29: Изоморфные react-приложения

- Разве это минусы?

Page 30: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

для бизнеса

снижение UX

30

Page 31: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

• Сложность поддержки

для бизнеса

снижение UX

риски

31

Page 32: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

• Сложность поддержки

• Пустая страница

для бизнеса

снижение UX

риски

проблемы SEO

32

Page 33: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

• Сложность поддержки

• Пустая страница

• Один URL

для бизнеса

снижение UX

риски

проблемы SEO

проблемы SMM

33

Page 34: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

• Сложность поддержки

• Пустая страница

• Один URL

• Legacy Browsers

для бизнеса

снижение UX

риски

проблемы SEO

проблемы SMM

потеря ЦА

34

Page 35: Изоморфные react-приложения

Single Page ApplicationМинусы

• Долгая загрузка

• Сложность поддержки

• Пустая страница

• Один URL

• Legacy Browsers

для бизнеса

снижение UX

риски

проблемы SEO

проблемы SMM

потеря ЦА

Расходы

Page 36: Изоморфные react-приложения

Single Page ApplicationМинусы

для бизнеса

снижение UX

риски

проблемы SEO

проблемы SMM

потеря ЦА

Расходы

Page 37: Изоморфные react-приложения

- WAT? Что делать?

Page 38: Изоморфные react-приложения

Взять лучшее из обоих миров

Page 39: Изоморфные react-приложения

Изоморфные приложения

Page 40: Изоморфные react-приложения

Изоморфные приложения

By isomorphic we mean that any given line of code (with notable exceptions) can execute both on the client and the server.

Charlie Robbins,18 Oct 2011

Page 41: Изоморфные react-приложения

Шаблоны

Стили

Локализация

Конфигурация

Routes

Права доступа

Модели

Схемы

Валидация

Сервисы

Изоморфные приложения

server.jsNode.js

worker.js

client.jsBrowser

admin.js

Бизнес-логика

Компоненты

API-интерфейсы

Actions, Reducers

Static Files

Page 42: Изоморфные react-приложения

Браузер

Изоморфные приложения

Front-end сервер

Back-end сервер

Database

Javaetc

Page 43: Изоморфные react-приложения

Браузер

Изоморфные приложения

Front-end сервер

Back-end сервер

Database

Javaetc

Page 44: Изоморфные react-приложения

Браузер

Изоморфные приложения

Front-end сервер

Back-end сервер

Database

Javaetc

- HTML - [critical CSS] - …

Page 45: Изоморфные react-приложения

Front-end клиент

Изоморфные приложения

Front-end сервер

Back-end сервер

Database

Javaetc

- HTML - [critical CSS] - JS Bundle

Page 46: Изоморфные react-приложения

Front-end клиент

Изоморфные приложения

Front-end сервер

Back-end сервер

Database

Javaetc

- HTML - [critical CSS] - JS Bundle

Page 47: Изоморфные react-приложения

Front-end клиент

Изоморфные приложения

Front-end сервер

• Единая среда исполнения

• Общая кодовая база

• Полный контроль

• Экосистема

47

Page 48: Изоморфные react-приложения

- Но как?

Page 49: Изоморфные react-приложения

Server-Side Rendering(SSR)

Page 50: Изоморфные react-приложения

Server-Side Rendering• Сборка HTML на Front-end сервере

• Моментальное отображение в

браузере, ещё до загрузки JS

• Когда JS загрузится, React только

добавит обработчики событий

• А это очень быстро50

Page 51: Изоморфные react-приложения

Server-Side RenderingКод на сервере выглядит очень просто:

import ReactDOMServer from 'react-dom/server';import Application from './components/application';const body = ReactDOMServer.renderToString( <Application />);

51

Page 52: Изоморфные react-приложения

Server-Side Rendering1. Пользователь видит страницу

мгновенно

2. Отсутствие дополнительных запросов на получение данных

3. Страница может работать даже без JS

4. Полноценная URL-навигация и мета-тэги

5. Сохранение всех возможностей современного JavaScript

52

Page 53: Изоморфные react-приложения

Часть 2

Page 54: Изоморфные react-приложения

Производительность и масштабирование

Page 55: Изоморфные react-приложения

Масштабирование

Page 56: Изоморфные react-приложения

Масштабированиефункциональное

Page 57: Изоморфные react-приложения

Server-Side RenderingВсё супер, когда данные есть:

import ReactDOMServer from 'react-dom/server';import Application from './components/application';const initialState = { siteName: ‘Startup Makers' };const body = ReactDOMServer.renderToString( <Application state={initialState} />);

57

Page 58: Изоморфные react-приложения

Server-Side RenderingВсё супер, когда данные есть:

import ReactDOMServer from 'react-dom/server';import Application from './components/application';const initialState = { siteName: ‘Startup Makers' };const body = ReactDOMServer.renderToString( <Application state={initialState} />);

Но если их надо получать извне?

58

Page 59: Изоморфные react-приложения

Server-Side RenderingКак получить асинхронный State:

1. Вручную для каждой страницы

2. Facebook Relay

3. redux-catch-promise

59

Page 60: Изоморфные react-приложения

Асинхронный StateВручную для каждой страницы:

• Получить State, необходимый для страницы

• ReactDOMServer.renderToString()

60

Page 61: Изоморфные react-приложения

Асинхронный StateFacebook Relay:

1. The framework for building data-driven React applications

2. Declarative. Colocation. Mutations.

3. https://github.com/facebook/relay/issues/136

4. 1Q201661

Page 62: Изоморфные react-приложения

Асинхронный Stateredux-catch-promise:

• Redux - state container для React

• Redux: the best for isomorphic apps, MoscowJS 25https://youtu.be/Uyk_8WWna6s

• redux-catch-promise - это middleware для Redux

62

Page 63: Изоморфные react-приложения

Асинхронный Stateredux-catch-promise:

1. callback для захвата Promise-экшнов

2. Делаем рендер компонент

3. Из компонент - запрос к БД, отдавая Promise

4. Собираем все эти промисы, ожидаем их завершения

5. Повторный рендер, с данными63

Page 64: Изоморфные react-приложения

Асинхронный Stateredux-catch-promise:

1. Примеры и исходный код:https://github.com/DenisIzmaylov/redux-catch-promise

2. Установка:

npm install redux-catch-promise

64

Page 65: Изоморфные react-приложения

Производительность

Page 66: Изоморфные react-приложения

Производительность

Тестовый стенд:

MacBook Pro 15” Retina (Early 2013)

2.4 GHz Intel Core i7

66

Page 67: Изоморфные react-приложения

ПроизводительностьРазмер страницы: 56 238 байт

Page 68: Изоморфные react-приложения

ПроизводительностьРазмер страницы: 56 238 байт

Page 69: Изоморфные react-приложения

ПроизводительностьРазмер страницы: 56 238 байт

Page 70: Изоморфные react-приложения

ПроизводительностьРазмер страницы: 56 238 байт

Page 71: Изоморфные react-приложения

ПроизводительностьРазмер страницы: 56 238 байт

Page 72: Изоморфные react-приложения

ПроизводительностьРазмер страницы: 56 238 байт

Page 73: Изоморфные react-приложения

Производительность

Для теста используем:

ab -n 100 http://localhost:3000/profile

73

Page 74: Изоморфные react-приложения

Производительность

Для теста используем:

ab -n 100 http://localhost:3000/profile

Запускаем…

74

Page 75: Изоморфные react-приложения

Производительность

Для теста используем:

ab -n 100 http://localhost:3000/profile

Запускаем…

Time per request: 61.850 ms

75

Page 76: Изоморфные react-приложения

Производительность

61.850 msЭто медленно или быстро?

76

Page 77: Изоморфные react-приложения

Производительность

61.850 msЭто медленно или быстро?

Тот же шаблон в Handlebars:

8.385 ms

86% less

77

Page 78: Изоморфные react-приложения

Производительность

61.850 msЭто медленно или быстро?

Тот же шаблон в Handlebars:

8.385 ms

86% less

78

Page 79: Изоморфные react-приложения

Производительность1. Идём в Google - ничего полезного

2. Пробуем спросить Twitter - тишина:

79

Page 80: Изоморфные react-приложения

Производительность

Ок, а что если?

NODE_ENV=production

Запускаем…

80

Page 81: Изоморфные react-приложения

Производительность

Ок, а что если?

NODE_ENV=production

Запускаем…

Time per request: 37.943 ms(vs 61.850 ms)

39% less81

Page 82: Изоморфные react-приложения

Производительность

Вроде лучше.

Но всё ещё не торт.

82

Page 83: Изоморфные react-приложения

Ищем дальше

Page 84: Изоморфные react-приложения

GitHub issues

Page 85: Изоморфные react-приложения

Производительность

• “Server rendering is slower with npm react”https://github.com/facebook/react/issues/812

85

Page 86: Изоморфные react-приложения

Производительность

• “Server rendering is slower with npm react”https://github.com/facebook/react/issues/812Решение:явно подключать react/dist/react.min.js

86

Page 87: Изоморфные react-приложения

ПроизводительностьСоздаём node_modules/react.js:if (process.env.NODE_ENV === 'production') {

module.exports = require('react/dist/react.min.js'); } else { module.exports = require('react/dist/react.js'); }

87

Page 88: Изоморфные react-приложения

ПроизводительностьСоздаём node_modules/react.js:if (process.env.NODE_ENV === 'production') {

module.exports = require('react/dist/react.min.js'); } else { module.exports = require('react/dist/react.js'); }

88

Page 89: Изоморфные react-приложения

Как это изменило результат?

Page 90: Изоморфные react-приложения

Производительность

Server rendering is slower with npm react

react/dist/react.min.js

Запускаем…

90

Page 91: Изоморфные react-приложения

Производительность

Server rendering is slower with npm react

react/dist/react.min.js

Запускаем…

Time per request: 38.253 ms(vs 37.943 ms)0.08% more

91

Page 92: Изоморфные react-приложения

Производительность

Server rendering is slower with npm react

react/dist/react.min.js

Запускаем…

Time per request: 38.253 ms(vs 37.943 ms)0.08% moreFAILED

92

Page 93: Изоморфные react-приложения

0

17,5

35

52,5

70

38,25337,943

8,385

61,85

React SSR Handlebars production react.min.js

Результаты

Page 94: Изоморфные react-приложения

0

17,5

35

52,5

70

38,25337,943

8,385

61,85

React SSR Handlebars production react.min.js

РезультатыNODE_ENV=production

39% less

Page 95: Изоморфные react-приложения

Часть 3

Page 96: Изоморфные react-приложения

Продвинутыерешения

Page 97: Изоморфные react-приложения

Продвинутые решения

1. Precompilation + Cache 2. Rendering Separation 3. Progressive Rendering 4. Facebook BigPipe 5. HAProxy

97

Page 98: Изоморфные react-приложения

Precompilation + Cache

• UI = f(state)

• f = React Component

• state = path + [actions] + …

1. Простое решение: redis

2. “Отложенный рендеринг”:redis + kue.js + workers 98

Page 99: Изоморфные react-приложения

Rendering Separation

99

Page 100: Изоморфные react-приложения

Progressive Rendering

100

Page 101: Изоморфные react-приложения

Progressive Rendering

• React DOM Stream

• Flushing the Document Early

• “Streams make this library as much as 47% faster in sending down a full page than ReactDOM.renderToString”

• Target - 108KB page on Heroku

• Time To First Byte (TTFB) - 55% faster

• https://github.com/aickin/react-dom-stream101

Page 102: Изоморфные react-приложения

Facebook BigPipe• Сборка страницы в процессе загрузки • Загружается параллельно • Устойчивость к ошибкам

Page 103: Изоморфные react-приложения

Facebook BigPipe• Сборка страницы в процессе загрузки • Загружается параллельно • Устойчивость к ошибкам

Page 104: Изоморфные react-приложения

Facebook BigPipe• Сборка страницы в процессе загрузки • Загружается параллельно • Устойчивость к ошибкам

Page 105: Изоморфные react-приложения

Facebook BigPipe

105

Page 106: Изоморфные react-приложения

HAProxy• Несколько экземпляров Node.js

• Обратитесь к DevOps

106

Page 107: Изоморфные react-приложения

Эпилог

Page 108: Изоморфные react-приложения

Рекомендации• Присоединяйтеськ сообществу MoscowJShttp://moscowjs.ru/

• Улучшайте английский, не читайте советских газет

• Читайте оригиналы и технические блоги

• Активно внедряйте в свою жизнь Twitter и GitHub

108

Page 109: Изоморфные react-приложения

Полезные материалы1. Supercharging page load (100 Days of Google Dev)

https://youtu.be/d5_6yHixpsQ 2. Making Netflix.com Faster

http://techblog.netflix.com/2015/08/making-netflixcom-faster.html

3. New technologies for the new LinkedIn home pagehttps://engineering.linkedin.com/frontend/new-technologies-new-linkedin-home-page

4. Improving performance on Twitter.comhttps://blog.twitter.com/2012/improving-performance-on-twittercom

5. Scaling Isomorphic Javascript Codehttp://blog.nodejitsu.com/scaling-isomorphic-javascript-code/

109

Page 110: Изоморфные react-приложения

Полезные материалы6. From AngularJS to React: The Isomorphic Way

https://blog.risingstack.com/from-angularjs-to-react-the-isomorphic-way/

7. Isomorphic JavaScript: The Future of Web Appshttp://nerds.airbnb.com/isomorphic-javascript-future-web-apps/

8. React server side rendering performancehttp://www.slideshare.net/nickdreckshage/react-meetup

9. The Lost Art of Progressive HTML Renderinghttp://blog.codinghorror.com/the-lost-art-of-progressive-html-rendering/

10. Extract and inline Critical Path CSS in HTML pages https://github.com/addyosmani/critical

110

Page 111: Изоморфные react-приложения

Послесловие«Большинство проблем

алгоритмов можно решить сменой структуры данных»,

Андрей Ситник

“Changes is our work”,Jake Archibald, Google

Page 112: Изоморфные react-приложения

Почему от классического Single Page Application необходимо отказаться?

Page 113: Изоморфные react-приложения

[email protected]

Присылайте свой мобильный телефони краткую информацию о себе

Page 114: Изоморфные react-приложения

Спасибо за внимание

Денис Измайлов

@DenisIzmaylov

https://github.com/DenisIzmaylov

http://startup-makers.ru

denis_izmaylov

[email protected]

Page 115: Изоморфные react-приложения

Приложение 1