Рендеринг может больше: vue.js vs react, Андрей Солодовников

Post on 15-Aug-2015

263 Views

Category:

Software

11 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Рендеринг может больше:

Vue.js vs ReactАндрей Солодовников

a.solodovnikov@office.ngs.ru

~ 2,5 годаFront-end developer

НГС.АвтоНГС.ПогодаНГС.Недвижимость

~ 1 годJavaScript developer

N1.ru

Обо мне

~6 летВелосипедист

~ 20 регионов РФ Объявления по недвижимости

~ 1 годНаходится в разработке

● Динамичный интерфейс Много мелких изменений прямо в браузере

● Быстро выпускать новые фичи Маленькая команда должа работать эффективно

● Поддерживаемость При большом количестве кода на новом уровне

● SEO Индексация поисковыми роботами

Начальные требования

Шаблонизацию и её виды

Клиентскийрендеринг

Серверныйрендеринг

Мы рассмотрим

Шаблонизация

HTML-шаблонизацияМонолитные строки с кодом

DOM-шаблонизацияДинамические элементы документа

Виды шаблонизации

HTML-шаблонизация

HTML-шаблонизаторы

● Handlebars

● Hogan.js

● dust.js

● Mustache.js

И другие

var tpl = Handlebars.compile( '<div>{{name}} <span>{{age}}</span></div>');

var html = tpl({name: 'Василий Николаевич', age: 32});

<div>Василий Николаевич <span>32</span></div>

Пример на Handlebars

Чем круто?

Скорость рендерингаСписок объявлений из 250 элементов за ~ 25ms

ПростотаНикакой “магии”. Задали шаблон, передали данные, получили результат

УниверсальностьМожно использовать как в браузере, таки под node.js

Чем не подходит?

НеповоротливостьОбновлять шаблоны приходится целиком

Сложно в динамикеЧем больше динамических изменений, тем тяжелее использовать

НесамостоятельностьНужны дополнительные инструменты для мелких модификаций

Как нам HTML-шаблонизация?

● Быстро, но неповоротливо Отличная скорость рендеринга, но не предусматривает мелких модификаций

● Требует дополнительных инструментов Нет единой системы контроля за разметкой

● Долго разрабатывать Вся логика изменений должна быть прописана явно и вручную

DOM-шаблонизация

Document Object ModelОбъектная модель документа

DOM-шаблонизаторы

● React

● Angular.js

● Vue.js

● Ractive.js

И другие

var div = document.createElement('div');

var text = document.createTextNode('Василий Николаевич ');

var age = document.createElement('span');

age.innerHTML = 32;

div.appendChild(text)

div.appendChild(age);

[ <div>Василий Николаевич <span>32</span></div> ]

DOM API

jQuery умеет

$('<div>Василий Николаевич <span>32</span></div>');

[ <div>Василий Николаевич <span>32</span></div> ]

Реактивностьvar data = { name: 'Василий Николаевич', age: 32};

> _

<div> Василий Николаевич <span>32<span></div>

Реактивностьvar data = { name: 'Василий Николаевич', age: 32};

data.age = 64;> _

<div> Василий Николаевич <span>64<span></div>

Чем огорчает?

Медленный запуск Первая инициализация может быть медленной

Много разметки - долго Нужно значительное время для обновления больших порций разметки

Чем круто?

Реактивность При обновлении данных автоматически обновляется разметка. Экономит время

СамостоятельностьДостаточно одного инструмента для контроля всей разметки

СкоростьПри мелких обновлениях разметки

Как нам DOM-шаблонизация?

● Уменьшает время выпуска новых фич Реактивность позволяет надёжно контролировать разметку

● Упрощает поддержку За счёт уменьшения количества ручных операций уменьшается код

● Единый инструмент контроля разметки Использовать jQuery и аналоги не обязательно

Итак, шаблонизация

HTML

1

2

3

5

DOM

5

5

5

1

Динамичность

Скрость разработки

Поддерживаемость

SEO

* cубъективная оценка

Выбираем инструментдля рендеринга

Исходные данные

React (v0.13.3)

IE8+

586 kb

118 kb

66 kb

Да

Vue.js (v0.12.7)

IE9+

221 kb

68 kb

22 kb

Нет

Поддержка браузеров

Размер

Размер minified

Размер minified gziped

Серверный рендеринг

Компоненты

Web ComponentsКастомный тег со своим шаблоном, стилями, скриптами

В более широком смыслеСамостоятельный функциональный блокс привязанными разметкой и стилями

var Example = React.createClass({ render: function () { return <div>{this.props.name} <span>{this.props.age}</span></div>; }});

JSX

var Example = React.createClass({ render: function () { return <div>{this.props.name} <span>{this.props.age}</span></div>; }});

JSX

var Example = React.createClass({ render: function () { return (React.createElement('div', null, this.props.name, ' ', React.createElement('span', null, this.props.age) )); }});

var app = React.render( <Example />, document.body);

Запуск приложенияvar Example = React.createClass({ getInitialState: function () { return {name: 'Василий Николаевич', age: 32}; }, render: function () { return <div>{this.state.name} <span>{this.state.age}</span></div>; }});

<body> <div data-reactid=".1"> <span data-reactid=".1.0">Василий Николаевич<span> <span data-reactid=".1.1"> <span> <span data-reactid=".1.2">32<span> </div></body>

Видимая разметка

<body> <div data-reactid=".1"> <span data-reactid=".1.0">Василий Николаевич<span> <span data-reactid=".1.1"> <span> <span data-reactid=".1.2">32<span> </div></body>

Видимая разметка

Virtual DOM Real DOM

PATCH

<body> <div data-reactid=".1"> <span data-reactid=".1.0">Василий Николаевич<span> <span data-reactid=".1.1"> <span> <span data-reactid=".1.2">32<span> </div></body>

Видимая разметка

> _

<body> <div data-reactid=".1"> <span data-reactid=".1.0">Василий Николаевич<span> <span data-reactid=".1.1"> <span> <span data-reactid=".1.2">64<span> </div></body>

Видимая разметка

app.setState({age: 64});> _

Динамические компонентыvar Strict = React.createClass({ render: function () { return <div>{this.props.name} <span>{this.props.age}</span></div>; }});

var Fancy = React.createClass({ render: function () { return (<div> Меня зовут {this.props.name} и мне сегодня <span>{this.props.age}</span> года </div>); }});

Динамические компонентыvar Example = React.createClass({ ... });

getInitialState: function () { return {name: 'Василий Николаевич', age: 32, view: 'strict'};}

switchView: function () { if (this.state.view === 'strict') { this.setState({'view': 'fancy'}); } else { this.setState({'view': 'strict'}); }}

Динамические компонентыrender: function () { var view; if (this.state.view === 'strict') { view = <Strict name={this.state.name} age={this.state.age} />; } if (this.state.view === 'fancy') { view = <Fancy name={this.state.name} age={this.state.age} />; }

return <div onClick={this.switchView}>{view}</div>;}

Динамические компоненты

Василий Николаевич 32

Меня зовут Василий Николаевич и мне сегодня 32 года

Запуск приложения

var Example = { el: 'body', data: { name: 'Василий Николаевич', age: 32 }};

var app = new Vue(Example);

<body><div>{{name}} <span>{{age}}<span></div></body>

<body> <div> Василий Николаевич <span>32<span> </div></body>

Видимая разметка

> _

<body> <div> Василий Николаевич <span>64<span> </div></body>

Видимая разметка

app.age = 64;> _

Динамические компонентыvar Strict = { props: ['name', 'age'], template: '<div>{{name}} <span>{{age}}</span></div>'};

var Fancy = { props: ['name', 'age'], template: '<div>' + 'Меня зовут {{name}} и мне сегодня <span>{{age}}</span> года' + '</div>'};

Динамические компоненты

data: { name: 'Василий Николаевич', age: 32, view: 'strict'}

components: {strict: Strict, fancy: Fancy}

var Example = { ... };

methods: { switchView: function () { if (this.view === 'strict') { this.view = 'fancy'; } else { this.view = 'strict'; } }}

Динамические компоненты<div v-on="click: switchView"> <div v-component="{{view}}" name="{{name}}" age="{{age}}"></div></div>

Динамические компоненты

Василий Николаевич 32

Меня зовут Василий Николаевич и мне сегодня 32 года

Пример: сила Vue.js

Один компонент Динамическая модель страницы

Связь между компонентами

http://n.gs/vue

Оценим “на глазок”

● Vue.js – ещё меньше кода В основе философии лежит простота и минимализм

● Vue.js – ещё проще работа с данными Использование нативных геттеров/сеттеров позволяет менять данные без вызова дополнительных функций

● Vue.js – динамичность ещё изящней Система динамических компонентов позволяет просто и понятно их переключать, отделять шаблоны от скриптов “из коробки”

Производительность: Браузер

Отрендерим список объявлений● 50 элементов

● 250 элементов

Core i3 @ 3.40GHz; Ubuntu 14.04

Рендеринг страницы

React

580 ms

1832 ms

Vue.js

302 ms

730 ms

50 объявлений

250 объявлений

* среднее время за 100 замеров

Добавление 1 элемента

React

175 ms

830 ms

Vue.js

12 ms

16 ms

50 объявлений

250 объявлений

* среднее время за 100 замеров

PureRenderMixin

● Использует shouldComponentUpdate Проверяет изменились ли данные и нужно ли запускать render

● Для компонентов с простыми данными Не может отследить изменения объектов

● Может значительно ускорить рендеринг Благодаря исключению вызовов render у неизменившихся компонентов

Добавление 1 элемента с PRM

React

12 ms

16 ms

Vue.js

12 ms

16 ms

50 объявлений

250 объявлений

* среднее время за 100 замеров

Полное обновление списка

React

232 ms

685 ms

Vue.js

238 ms

670 ms

50 объявлений

250 объявлений

* среднее время за 100 замеров

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

Окружение

● io.js v2.40 Для запуска тестов

● Express v4.13.1 Для вывода в браузер

● Jsdom v5.6.1 Для эмуляции документа на сервере

Что будем тестировать

● React.renderToString() Время исполнения

● React.renderToStaticMarkup() Время исполнения

● Vue.js под jsdom От запуска jsdom до исполнения new Vue()

Рендеринг списка из 250 элементов

Время

5202 ms

Размер страницы

1.5 MBReact.renderToString()

* среднее время за 100 замеров

Рендеринг списка из 250 элементов

Время

5202 ms

4883 ms

Размер страницы

1.5 MB

0.8 MB

React.renderToString()

React.renderToStaticMarkup()

* среднее время за 100 замеров

Рендеринг списка из 250 элементов

Время

5202 ms

4883 ms

5854 ms

Размер страницы

1.5 MB

0.8 MB

0.8 MB

React.renderToString()

React.renderToStaticMarkup()

Vue.js + jsdom

* среднее время за 100 замеров

React (node)

1250 msВремя

по данным http://www.slideshare.net/nickdreckshage/react-meetup

React* (node)

650 ms

Hogan (node)

450 ms

Mustache (go)

30 ms

* используя best practices

Сторонняя оценка

VueServer.js

Повторяет результат Vue.js

Без эмуляции DOM Асинхронный

Рендеринг списка из 250 элементов

Время

5202 ms

4883 ms

5854 ms

166 ms

Размер страницы

1.5 MB

0.8 MB

0.8 MB

0.8 MB

React.renderToString()

React.renderToStaticMarkup()

Vue.js + jsdom

VueServer.js

* среднее время за 100 замеров

Подведём итог

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

React

1832 ms

16 ms

685 ms

4883 ms

Vue.js

730 ms

16 ms

670 ms

5854 ms / 166 ms*

Рендеринг FE

Добавление 1 элемента

Замена списка целиком

Рендеринг BE

* c использованием VueServer.js

Итоговая оценка по требованиям

React

4

3

5

1

Vue.js

5

5

5

1 / 5*

Динамичность

Скрость разработки

Поддерживаемость

SEO

cубъективная оценка

* c использованием VueServer.js

Спасибо за внимание!Вопросы?

Андрей СолодовниковJS-разработчик НГСa.solodovnikov@office.ngs.ru

● http://n.gs/vue Пример на Vue.js с QR-кода

● http://n.gs/perf Тесты производительности

top related