Плюсы и минусы реакции Facebook против веб-компонентов (полимер)


521

Каковы основные преимущества React от Facebook перед предстоящей спецификацией веб-компонентов и наоборот (или, может быть, сравнение между яблоками и яблоками было бы более значительным по сравнению с библиотекой Google Polymer )?

Согласно этому докладу об ЕС и домашней странице React, основными преимуществами React являются:

  • Разъединение и увеличение сцепления с использованием компонентной модели
  • Абстракция, Композиция и Экспрессивность
  • Виртуальные события DOM & Synthetic (что в основном означает, что они полностью повторно реализовали DOM и его систему событий)
    • Включает современные события HTML5 события в IE 8
    • Рендеринг на стороне сервера
    • способность быть свидетелем в суде
    • Привязки к SVG, VML и <canvas>

Почти все упомянутое изначально встроено в браузеры через веб-компоненты, кроме этой концепции виртуального DOM (очевидно). Я могу видеть, как виртуальные DOM и синтетические события могут быть полезны сегодня для поддержки старых браузеров, но разве не выбрасывает огромный кусок нативного кода браузера, как будто вы стреляете себе в ногу в долгосрочной перспективе? Что касается современных браузеров, не слишком ли много ненужных накладных расходов / изобретений колеса?

Вот некоторые вещи, которые, по моему мнению, отсутствуют в React, и веб-компоненты позаботятся о вас. Поправьте меня если я ошибаюсь.

  • Встроенная поддержка браузера (читайте "гарантированно быстрее")
  • Написание сценария на языке сценариев, написание стилей на языке стилей, написание разметки на языке разметки.
  • Инкапсуляция стилей с использованием Shadow DOM
    • Вместо этого React имеет это , что требует написания CSS на JavaScript. Не красиво
  • Двухстороннее связывание

12
Wrt. двухстороннее связывание. Эта функция проблематична в масштабе. В тривиальных случаях это работает хорошо, но в реальных случаях вы, как правило, обнаруживаете, что для сохранения управляемости кода вам требуется привязка к модели представления вместо привязки к реальной модели, что делает двустороннее связывание гораздо менее полезным, чем изначально казалось. Я думаю, что преимущество React может заключаться в том, что он не обеспечивает двустороннюю привязку, потому что он обеспечивает правильную архитектуру потока данных.
Джори Себрехтс

8
Я посмотрел на React, Angular и Knockout. Я считаю Knockout «самым чистым» с точки зрения разделения шаблонов пользовательского интерфейса, данных и привязки. Я хотел бы отреагировать, но, пытаясь создать простой Combobox, я понимаю, что писал гораздо больше кода и смешивал логику рендеринга с HTML-шаблонизаторами ... гораздо больше, чем я бы использовал что-то вроде html / jina2. Мне кажется, что эти библиотеки / API перемещают нас назад, а не вперед. Лучше всего в React является виртуальная манипуляция с dom, но я вижу, что переход к другим установленным фреймворкам происходит раньше, чем позже.
mike01010

41
Я очень удивлен (и также рад!), Что этот вопрос не был закрыт как «в первую очередь основанный на мнении».
иконоборчество

4
Невозможно написать «скрипт на языке сценариев» и «разметку на языке разметки», если вы делаете шаблонирование любого рода. Угловой, полимерный и т. Д. Используют шаблон DSL, встроенный в HTML. React использует шаблон DSL, встроенный в JS (JSX). Проблема с внедрением DSL в HTML состоит в том, как установить область для получения значений из JS. Это приводит к сложной $ scope системе Angular. В JSX, с другой стороны, область видимости переменных в шаблонах - это просто область видимости JS - я нахожу это гораздо менее запутанным.
Энди

3
В настоящий момент компоненты React (если не написаны плохо) будут быстрее, чем те же в любой DOM-связанной среде. V-dom и рассеянная магия - это USP реакции. Моя точка зрения - почему бы браузерам не создавать подобные различия в своем родном наборе функций. Что их останавливает, а если ничего (останавливает), то лидерство Реакта, вероятно, будет недолгим.
fasttrainofhowts

Ответы:


664

Обновление:  этот ответ кажется довольно популярным, поэтому я потратил некоторое время, чтобы немного его очистить, добавить новую информацию и прояснить несколько вещей, которые, на мой взгляд, были недостаточно ясными. Пожалуйста, прокомментируйте, если вы считаете, что что-то еще требует уточнения или обновления.

Большинство ваших проблем на самом деле зависит от мнений и личных предпочтений, но я постараюсь ответить максимально объективно:

Родной или скомпилированный

Пишите JavaScript в vanilla JavaScript, пишите CSS в CSS, пишите HTML в HTML.

Когда-то были горячие споры о том, нужно ли писать нативную  сборку вручную или использовать язык более высокого уровня, например C, чтобы компилятор генерировал код сборки для вас. Еще до этого люди отказывались доверять ассемблерам и предпочитали писать машинный код вручную ( и я не шучу ).

Между тем, сегодня есть много людей, которые пишут HTML на Haml или Jade , CSS на Sass или Less и JavaScript на CoffeeScript или TypeScript . Это здесь. Оно работает. Некоторые люди предпочитают это, некоторые нет.

Дело в том, что нет ничего принципиально неправильного в том, чтобы не писать JavaScript на обычном JavaScript, CSS на CSS и HTML на HTML. Это действительно вопрос предпочтений.

Внутренние и внешние DSL

 Инкапсуляция стилей с использованием Shadow DOM React вместо этого имеет это, что требует написания CSS на JavaScript. Не красиво

Красиво или нет, это, конечно, выразительно. JavaScript - очень мощный язык, намного более мощный, чем CSS (даже включая любой из препроцессоров CSS). Это зависит от того, предпочитаете ли вы внутренние или внешние DSL для такого рода вещей. Опять же, вопрос предпочтений.

(Примечание: я говорил о встроенных стилях в React, на которые ссылался оригинальный вопрос.)

Типы DSL - объяснение

Обновление: читая мой ответ через некоторое время после его написания, я думаю, что мне нужно объяснить, что я имею в виду здесь. DSL является предметно-ориентированным языком и может быть внутренним (с использованием синтаксиса основного языка, такого как JavaScript - как, например, React без JSX, или, как встроенные стили в React, упомянутом выше), или может быть внешним (с использованием другого синтаксиса чем язык хоста - как в этом примере будет встроить CSS (внешний DSL) в JavaScript).

Это может сбивать с толку, потому что в некоторых литературах для описания этих типов DSL используются термины, отличные от «внутренних» и «внешних». Иногда вместо встроенного используется «встроенный», но слово «встроенный» может означать разные вещи - например, Lua описывается как «Lua: расширяемый встроенный язык», где внедренный не имеет ничего общего со встроенным (внутренним) DSL (в в этом смысле это совсем наоборот - внешний DSL), но это означает, что он встроен в том же смысле, что, скажем, SQLite является встроенной базой данных. Существует даже eLua, где «e» означает «встроенный» в третьем смысле - что он предназначен для встроенных систем! Вот почему я не люблю использовать термин «встроенный DSL», потому что такие вещи, как eLua, могут быть «DSL», которые «встроены» в двух разных смыслах, но вовсе не являются «встроенными DSL»!

Что еще хуже, некоторые проекты вносят еще большую путаницу в микс. Например. Шаблоны Flatiron описаны как «свободные от DSL», хотя на самом деле это просто прекрасный пример внутреннего DSL с синтаксисом, например:map.where('href').is('/').insert('newurl');

При этом, когда я писал: «JavaScript - очень мощный язык, гораздо более мощный, чем CSS (даже включая любой из препроцессоров CSS). Это зависит от того, предпочитаете ли вы внутренние или внешние DSL для такого рода вещей. Опять же, вопрос предпочтения ". Я говорил об этих двух сценариях:

Один:

/** @jsx React.DOM */
var colored = {
  color: myColor
};
React.renderComponent(<div style={colored}>Hello World!</div>, mountNode);

Два:

// SASS:
.colored {
  color: $my-color;
}
// HTML:
<div class="colored">Hello World!</div>

В первом примере используется то, что было описано в вопросе как: «написание CSS на JavaScript. Не красиво». Второй пример использует Sass. Хотя я согласен, что использование JavaScript для написания CSS может быть не очень красивым (для некоторых определений «довольно»), но есть одно преимущество в этом.

У меня могут быть переменные и функции в Sass, но имеют ли они лексическую или динамическую область? Они статически или динамически типизированы? Сильно или слабо? Как насчет числовых типов? Типа принуждения? Какие ценности являются правдивыми, а какие ложными? Могу ли я иметь функции высшего порядка? Рекурсия? Хвостовые звонки? Лексические затворы? Оцениваются ли они в обычном или аппликативном порядке? Есть ли ленивая или нетерпеливая оценка? Аргументы функций передаются по значению или по ссылке? Они изменчивы? Неизменный? Стойкие? Как насчет объектов? Классы? Прототипы? Наследование?

Это не тривиальные вопросы, и все же я должен знать ответы на них, если я хочу понять код Sass or Less. Я уже знаю эти ответы для JavaScript, так что это означает, что я уже понимаю каждый внутренний DSL (например, встроенные стили в React) на этих самых уровнях, поэтому, если я использую React, мне нужно знать только один набор ответов на них (и многие похожие ) вопросы, а когда я использую для например. Sass и Handlebars, тогда я должен знать три набора этих ответов и понять их значение.

Нельзя сказать, что так или иначе всегда лучше, но каждый раз, когда вы вводите в микс другой язык, вы платите какую-то цену, которая может быть не столь очевидной на первый взгляд, и эта цена сложна.

Надеюсь, я немного разъяснил, что я имел в виду.

Привязка данных

Двухстороннее связывание

Это действительно интересная тема, а на самом деле также вопрос предпочтений. Двусторонняя не всегда лучше односторонней. Вопрос в том, как вы хотите смоделировать изменяемое состояние в вашем приложении. Я всегда рассматривал двусторонние привязки как идею, несколько противоречащую принципам функционального программирования, но функциональное программирование - не единственная парадигма, которая работает, некоторые люди предпочитают такой тип поведения, и оба подхода на практике работают довольно хорошо. Если вам интересны подробности проектных решений, связанных с моделированием состояния в React, посмотрите доклад Пита Ханта (связанный с этим вопросом) и доклад Тома Оккино и Джордана Уолка,  которые очень хорошо объясняют это в мое мнение.

Обновление: см. Также другой доклад Пита Ханта: « Будь предсказуемым, а не правильным: функциональное программирование DOM» .

Обновление 2: Стоит отметить, что многие разработчики выступают против двунаправленного потока данных или двусторонней привязки, некоторые даже называют это анти-паттерном. Возьмем, к примеру, архитектуру приложений Flux, которая явно избегает модели MVC (которую трудно масштабировать для больших приложений Facebook и Instagram) в пользу строго однонаправленного потока данных (см. Путь Хакера: переосмысление разработки веб-приложений на Facebook , Том Оккино, Цзин Чен и Пит Хант за хорошее представление). Кроме того, много критики против AngularJS (самая популярная веб-инфраструктура, в основе которой лежит модель MVC, известная как двусторонняя привязка данных), включает аргументы против этого двунаправленного потока данных, см .:

Обновление 3: Еще одна интересная статья, которая хорошо объясняет некоторые из обсуждаемых выше проблем, - это деконструкция потока ReactJS - не использовать MVC с ReactJS от Микаэля Брассмана, автора RefluxJS (простой библиотеки для однонаправленной архитектуры приложений потока данных, вдохновленной Flux).

Обновление 4: Ember.js в настоящее время удаляется от двусторонней привязки данных, и в будущих версиях он будет односторонним по умолчанию. См .: «Будущее Эмбер», выступление Стефана Пеннера на симпозиуме «Эмбергартен» в Торонто 15 ноября 2014 года.

Обновление 5: См. Также: «Дорога к Ember 2.0 RFC» - интересное обсуждение в запросе на извлечение Тома Дейла :

«Когда мы разрабатывали оригинальный шаблонный слой, мы полагали, что создание двухсторонних привязок данных не очень вредно: если вы не установите двустороннюю привязку, это де-факто односторонняя привязка!

С тех пор мы поняли (с некоторой помощью наших друзей из React), что компоненты хотят иметь возможность передавать данные своим детям, не заботясь о своенравных мутациях.

Кроме того, связь между компонентами часто наиболее естественно выражается в виде событий или обратных вызовов . Это возможно в Ember, но доминирование двусторонних привязок данных часто приводит людей к пути использования двусторонних привязок в качестве канала связи . Опытные разработчики Ember (как правило) не делают эту ошибку, но ее легко сделать ». [Выделение добавлено]

Родной против ВМ

Встроенная поддержка браузера (читайте "гарантированно быстрее")

Теперь наконец то, что не является вопросом мнения.

На самом деле здесь все наоборот. Конечно, «родной» код может быть написан на C ++, но как вы думаете, на чем написаны движки JavaScript?

На самом деле движки JavaScript поистине удивительны в тех оптимизациях, которые они используют сегодня - и уже не только V8, но и SpiderMonkey и даже Chakra в наши дни. И имейте в виду, что с JIT-компиляторами код не только настолько естественный, насколько это возможно, но также есть возможности оптимизации во время выполнения, которые просто невозможно сделать в любом статически скомпилированном коде.

Когда люди думают, что JavaScript медленный, они обычно имеют в виду JavaScript, который обращается к DOM. DOM медленный. Это нативный код, написанный на C ++, и все же он медленный из-за сложности, которую он должен реализовать.

Откройте консоль и напишите:

console.dir(document.createElement('div'));

и посмотрите, сколько свойств должен реализовать пустой divэлемент, который даже не присоединен к DOM. Это только  свойства первого уровня, которые являются «собственными свойствами», т.е. не наследуется от прототипа цепочки:

выравнивание, ожидание, onvolumechange, ontimeupdate, onsuspend, onsmit, onstald, onshow, onselect, onking onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, односторонний, ondurationchange, ondrop, ondragstart, ondragover, ondrag oncontextmenu, OnClose, OnClick, OnChange, oncanplaythrough, oncanplay, OnCancel, ONBLUR, OnAbort, проверка орфографии, isContentEditable, contentEditable, outerText, InnerText, Accesskey, скрытый, webkitdropzone, перетаскивать, TabIndex, реж, перевод, языки, название, childElementCount, lastElementChild,firstElementChild, дети, nextElementSibling, previousElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onselectstart, onsearch, onpaste, oncut, oncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, набор данных, ClassList, имя класса, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, префикс, namespaceURI, идентификатор, стиль, атрибуты, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, previousSibling, firstSibling, lastChildChildChildChildC parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, набор данных, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientWidth, смещение, смещение, смещение, смещение, выкл namespaceURI, id, стиль, атрибуты, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, набор данных, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientWidth, смещение, смещение, смещение, смещение, выкл namespaceURI, id, стиль, атрибуты, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameparentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeName

Многие из них на самом деле являются вложенными объектами - чтобы увидеть свойства второго уровня (собственные) пустого натива divв вашем браузере, посмотрите эту скрипку .

Я имею в виду серьезно, свойство onvolumechange на каждом узле div? Это ошибка? Нет, это просто традиционная версия модели событий DOM Level 0 одного из обработчиков событий, «которая должна поддерживаться всеми элементами HTML , как атрибутами содержимого, так и атрибутами IDL» [выделение добавлено] в Разделе 6.1.6.2 спецификации HTML. по W3C - никак не обойтись.

Между тем, это свойства первого уровня поддельного DOM divв React:

props, _owner, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

Разница не так ли? Фактически это весь объект, сериализованный в JSON ( LIVE DEMO ), потому что на самом деле вы можете  сериализовать его в JSON, поскольку он не содержит никаких циклических ссылок - что-то немыслимое в мире нативного DOM ( где он просто генерирует исключение) ):

{
  "props": {},
  "_owner": null,
  "_lifeCycleState": "UNMOUNTED",
  "_pendingProps": null,
  "_pendingCallbacks": null,
  "_pendingOwner": null
}

Это в значительной степени главная причина, почему React может быть быстрее, чем DOM собственного браузера - потому что он не должен реализовывать этот беспорядок .

Посмотрите эту презентацию Стивена Люшера, чтобы увидеть, что быстрее: нативный DOM, написанный на C ++, или фальшивый DOM, написанный полностью на JavaScript. Это очень справедливая и интересная презентация.

Обновление: Ember.js в будущих версиях будет использовать виртуальный DOM, вдохновленный React, для улучшения производительности. См .: «Будущее Эмбер», выступление Стефана Пеннера на симпозиуме «Эмбергартен» в Торонто 15 ноября 2014 года.

Подводя итог, можно сказать, что функции веб-компонентов, такие как шаблоны, привязка данных или пользовательские элементы, будут иметь много преимуществ по сравнению с React, но до тех пор, пока сама объектная модель документа не будет значительно упрощена, производительность не будет одной из них.

Обновить

Через два месяца после того, как я опубликовал эти ответы, появились некоторые новости, которые актуальны здесь. Как я только что написал в Twitter , последняя версия текстового редактора Atom, написанного GitHub на JavaScript, использует React Facebook для повышения производительности, даже если согласно Википедии «Atom основан на Chromium и написан на C ++», поэтому он имеет полный контроль над нативная реализация C ++ DOM (см . Ядро Atom ) и гарантированно будет иметь поддержку веб-компонентов, так как он поставляется с собственным веб-браузером. Это всего лишь недавний пример реального проекта, который мог бы использовать любой другой вид оптимизации, обычно недоступный для веб-приложений, и все же он решил использовать React, который сам написан на JavaScript, для достижения максимальной производительности, даже при том, что Atom не был построен с React с самого начала, поэтому это не было тривиальным изменением.

Обновление 2

У Тодда Паркера есть интересное сравнение с использованием WebPagetest для сравнения производительности примеров TodoMVC, написанных на Angular, Backbone, Ember, Polymer, CanJS, YUI, Knockout, React и Shoestring. Это самое объективное сравнение, которое я видел до сих пор. Здесь важно то, что все соответствующие примеры были написаны экспертами во всех этих средах, все они доступны на GitHub и могут быть улучшены любым, кто считает, что часть кода может быть оптимизирована для более быстрой работы.

Обновление 3

Ember.js в будущих версиях будет включать в себя ряд функций React, которые обсуждаются здесь (включая виртуальную DOM и однонаправленную привязку данных, и многие другие), что означает, что идеи, которые возникли в React, уже переносятся в другие среды. См .: Дорога к Ember 2.0 RFC - интересное обсуждение в запросе на извлечение Тома Дейла (дата начала: 2014-12-03): «В Ember 2.0 мы примем« виртуальный DOM »и модель потока данных, которая охватывает лучшие идеи от React и упрощает связь между компонентами. "

Кроме того, Angular.js 2.0 реализует множество концепций, обсуждаемых здесь.

Обновление 4

Я должен остановиться на нескольких вопросах, чтобы ответить на этот комментарий Игве Калу:

«не имеет смысла сравнивать React (JSX или выходные данные компиляции) с простым JavaScript, когда React в конечном итоге сводится к простому JavaScript. [...] Какую бы стратегию React не использовал для вставки DOM, ее можно применять без использования React. не добавляет никаких особых преимуществ при рассмотрении рассматриваемой функции, кроме удобства. " (полный комментарий здесь )

В случае, если это не было достаточно ясно, в части моего ответа я сравниваю производительность работы непосредственно на собственном DOM (реализованном в виде хост-объектов в браузере) с поддельным / виртуальным DOM React (реализованным в JavaScript). Дело в том что я пытался сделать это , что виртуальный DOM реализован в JavaScript может опережать реальный DOM , реализованный в C ++ и не что React может опережать JavaScript (который , очевидно , не имеет особого смысла , так как это будет написано в JavaScript). Моя точка зрения заключалась в том, что «родной» код C ++ не всегда гарантированно работает быстрее, чем «не родной» JavaScript. Использование React для иллюстрации этого вопроса было только примером.

Но этот комментарий затронул интересную проблему. В некотором смысле это правда, что вам не нужна какая-либо инфраструктура (React, Angular или jQuery) по какой-либо причине (например, производительность, переносимость, функции), потому что вы всегда можете воссоздать то, что среда делает для вас, и заново изобретать колесо - если Вы можете обосновать стоимость, то есть.

Но - как хорошо выразился Дейв Смит в статье Как упустить момент при сравнении производительности веб-фреймворка : «При сравнении двух веб-фреймворков вопрос не в том, может ли мое приложение быть быстрым с фреймворком X. Вопрос в том, будет ли мое приложение быстрым с фреймворком ИКС."

В своем ответе от 2011 года: по каким-то эмпирическим техническим причинам не использовать jQuery я объясняю аналогичную проблему: невозможно написать переносимый код для манипулирования DOM без такой библиотеки, как jQuery, но люди редко делают это.

При использовании языков программирования, библиотек или фреймворков люди склонны использовать самые удобные или идиоматические способы ведения дел, а не совершенные, но неудобные. Истинная ценность хороших фреймворков заключается в том, чтобы упростить то, что в противном случае было бы трудно сделать, и секрет в том, чтобы сделать правильные вещи удобными. В результате в вашем распоряжении все та же сила, что и у простейшей формы лямбда-исчисления или самой примитивной машины Тьюринга, но относительная выразительность некоторых понятий означает, что эти самые понятия имеют тенденцию выражаться легче или вообще, и что правильные решения не только возможны, но и широко применяются.

Обновление 5

Реагировать + Производительность =? В статье Пола Льюиса от июля 2015 года приведен пример, в котором React медленнее, чем ванильный JavaScript, написанный вручную для бесконечного списка картинок Flickr, что особенно важно для мобильных устройств. Этот пример показывает, что каждый должен всегда тестировать производительность для конкретного варианта использования и конкретных целевых платформ и устройств.

Спасибо Кевину Лозандье за то, что он привлек мое внимание .


75
это то, что я называю исчерпывающим ответом, спасибо!
Демвунц

14
Похоже, Атом удаляется от Реакта. См. Github.com/atom/atom/issues/3677 .
Юхо Вепсяляйнен

6
@ash: Если вы будете читать дальше, они расскажут о том, как они хотели бы в конечном итоге полностью отойти от React и других фреймворков и просто свернуть свои собственные, используя пользовательские элементы и теневой DOM.
musicfreak

3
Просто чтобы прояснить вышеприведенную формулировку, в списке @ErikAllik FRP (Функциональное Реактивное Программирование) - это не новый язык, а скорее набирающий популярность подход. Фактически, «Elm основан на идее функционально-реактивного программирования» (из elm-lang.org), и, как он упомянул, существуют платформы FRP для Haskell и т. Д.
Джон Кумбс

5
tl; все равно читай - гениальный, подробный ответ!
Марк К Коуэн

16

Полимер потрясающий. Реакция потрясающая. Они не одно и то же.

Polymer - это библиотека для создания обратно совместимых веб-компонентов.

Реагировать является V в MVC. Это вид, и ничего больше. По крайней мере, само по себе.

Реагировать не является основой.

React + Flux + Node + (Gulp или Grunt) более сопоставим с фреймворком, но 3 из этих вещей вообще не являются частью реакции.

Существует множество технологий, шаблонов и архитектурных стилей, за которыми следуют разработчики, но сама реакция не является основой.

Печально, что никто не нашел время, чтобы сказать самую простую вещь, которую они не должны сравнивать. У них есть некоторые совпадения, но они больше, чем то же самое.

Они оба позволяют вам определять веб-компоненты, но по-разному. Кроме того, они очень разные инструменты.


Разве React не является одновременно M и V, а не только V, поскольку он хранит и обновляет состояние данных и отображает фрагменты html через компоненты?
abelito

1
Существуют библиотеки управления состояниями реагирования, такие как flux или redux, но они не включены в реагирование.
Робоцуши

О, я вижу, мы не считаем данные представления данными модели ... пока они не будут переданы на серверную часть. Несмотря на то, что React хранит состояние компонента (просмотр данных), он остается для просмотра данных до отправки. Это имеет смысл.
abelito

15

Ребята из React довольно неплохо объясняют сравнение между React и веб-компонентами:

Попытка сравнить и сопоставить React с WebComponents неизбежно приводит к осмысленным выводам, поскольку две библиотеки созданы для решения разных задач. WebComponents обеспечивают надежную инкапсуляцию для повторно используемых компонентов, в то время как React предоставляет декларативную библиотеку, которая синхронизирует DOM с вашими данными. Две цели дополняют друг друга; инженеры могут смешивать и сочетать технологии. Как разработчик, вы можете свободно использовать React в своих WebComponents, или использовать WebComponents в React, или и то, и другое.


14

Еще один ответ в одном конкретном случае:

Пишите JavaScript в vanilla JavaScript, пишите CSS в CSS, пишите HTML в HTML.

Ничто не мешает вам писать Javascript, скажем, CoffeeScript, TypeScript, ClojureScript или что-либо еще. Это чисто вопрос предпочтений.

HTML - лучший DSL для статических документов HTML. Но это ничего не дает для динамического HTML. А в браузере лучшим языком для создания динамического HTML является Javascript, а не чистый HTML со специальными манипуляциями с Javascript DOM или язык шаблонов, такой как Handlebars, которые даже не являются наполовину языками.

Для CSS, если ваш CSS является статическим, вы пишете это как обычно. Если он должен быть динамическим на основе некоторых значений времени выполнения, это та же история, что и в HTML: Javascript - лучший способ сделать его динамичным.


1
Я ценю ответ, но на самом деле это не моя точка зрения. Надеюсь, мои правки сделали вопрос немного яснее?
CletusW

1
Извините, это не так. Вы по-прежнему можете написать свой стиль на любом языке стилей в отдельном файле. А в JSX от React создается впечатление, что вы используете язык разметки.
DjebbZ

3
«Javascript - это лучший способ сделать [CSS] динамическим» - просто сказать, что это не объясняет, почему.
Пилау

1
Хорошо, если стили / классы должны меняться в соответствии с пользовательским вводом или бизнес-правилами, просто используйте javascript для их изменения. В vanilla js вы должны манипулировать свойствами classList или styles узла DOM. С React вы можете достичь той же цели, управляя Virtual DOM. Это понятнее?
DjebbZ

2
Vjeux, основной участник React, недавно выступил с докладом, в котором он использует концепцию «CSS в JS» с помощью React. Я думаю, что это интересно, вы, возможно, захотите посмотреть, о чем это: blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
DjebbZ

6

Я не использовал веб-компоненты, но похоже, что они требуют, чтобы вы добавили вручную закодированную логику мутации в обработчики событий.

фрагмент из примера Polymer:

 <script>
   Polymer({
     counterChanged: function() {
       this.$.counterVal.classList.add('highlight');
     },
 ...

Весь смысл React состоит в том, чтобы уменьшить сложность за счет устранения логики мутаций. Вместо этого вы наивно регенерируете виртуальный DOM и позволяете алгоритму сравнения React выяснить, что нужно изменить в реальном DOM.


5
Не уверен, где вы взяли этот пример, но Polymer также не рекомендует ручную мутацию DOM в пользу привязки данных, в том числе для имен классов .
CletusW

Это пример с вкладки «Создать элементы» на главной странице Polymer-project.org .
Лимкодер

4
Вау, ты прав! Я думаю, они просто хотели пример автоматического поиска узлов. Это, вероятно, не лучший, чтобы дать, хотя.
CletusW

6

Я думаю, что самым большим недостатком React, на мой взгляд, является то, что он не основан на веб-стандартах. В настоящий момент React является очень мощным инструментом, но поскольку он по возможности обходит все, что предоставляет браузер, решения, которые, казалось бы, сейчас имеют смысл, скорее всего, не будут иметь смысла через несколько лет, поскольку встроенные средства браузера продолжают улучшить. Поэтому я хотел бы поговорить об этом и о том, как это влияет на несколько различных аспектов веб-приложений.

Представление

Люди любят утверждать, что преимущество React состоит в том, что он полностью заново изобретает всю модель DOM и модель событий, а существующая стандартная модель DOM тяжелая и дорогая, а что нет, но в итоге я не нашел производительности Реагируйте лучше, чем то, что я могу получить из хорошо написанного приложения Backbone или Polymer. На самом деле, по большей части моего профессионального опыта, производительность React была немного хуже. Это не значит, что React медленен ... Это просто не самый передовой выбор производительности, о котором мы все думали, что это было до того, как мы заполучили его.

В ответе на rsp он указывает, что DOM-модель React для DIV намного легче, чем нативный DOM-DIV, и это, безусловно, так. Однако, чтобы React был полезным, этот «виртуальный» div должен в конечном итоге стать настоящим div. Так что, с моей точки зрения, дело не в том, чтобы разделить React против нативного div. Это React div + нативный div против просто нативного div. Издержки версии DOM от React нетривиальны, и если стандарты когда-нибудь отбросят некоторые из этих ненужных атрибутов и позволят нативным узлам DOM стать намного легче, внезапно эти издержки будут казаться действительно дорогими.

В одном из моих предыдущих мест работы у нас было несколько приложений в Polymer и несколько приложений в React. Одно из ранних приложений Polymer закончилось переписыванием в React, потому что это было стандартом для компании, и, основываясь на измерениях, я взял версию React этого же приложения, использующего примерно на 30% больше памяти, чем версия Polymer. и, хотя разница была незначительной, версия Polymer также отображалась за меньшее время. Здесь нужно учитывать одну вещь: мы говорим о приложениях, написанных людьми, и люди не совершенны, поэтому может быть возможно, что реализация этого приложения в React не использует все возможности React. Но я думаю, что, по крайней мере, некоторые из них связаны с накладными расходами React, связанными с наличием собственной версии DOM.

React заново изобретает весь DOM, используя свою собственную модель, а затем использует ее для значительной оптимизации производительности. Представление отображается в виртуальном DOM, и это проецируется в реальный DOM. Когда есть изменение, и представление должно быть обновлено, представление снова заново визуализируется в виртуальный DOM, и это дерево сравнивается с предыдущим деревом, чтобы определить, какие узлы должны быть изменены в реальном DOM, чтобы отразить это изменение. в представлении. Хотя это очень умный подход к созданию эффективных обновлений DOM, необходимо поддерживать все эти виртуальные деревья DOM и анализировать их, чтобы определить, что следует изменить в реальном DOM. В настоящее время эти издержки значительно компенсируются выигрышами в производительности, но по мере того, как собственный DOM со временем улучшается, масштаб будет смещаться в другом направлении. Я беспокоюсь о том, как приложения React могут стареть, и если через 3 года они будут намного медленнее, чем вещи, которые напрямую связаны с DOM. Этот виртуальный подход к DOM является своего рода кувалдой, и другие библиотеки, такие как Polymer, смогли реализовать очень эффективные подходы для работы с DOM гораздо более тонким способом.

Обновление для производительности: одна из библиотек, с которой я столкнулся некоторое время назад, делает то, что я считаю лучше справляться с управлением обновлениями DOM. Это библиотека Incremental Dom от Google, и я думаю, что тот факт, что она работает с dom на месте и не требует создания «виртуальной копии», является гораздо более чистым подходом с гораздо меньшими накладными расходами памяти. Подробнее здесь: http://google.github.io/incremental-dom/#about

Декларативные и обязательные компоненты

Когда вы говорите о компонентной составляющей вашего приложения, вы всегда слышите о преимуществах декларативных компонентов. В мировоззрении React все красиво и декларативно. Вы пишете JavaScript, который возвращает разметку, а React склеивает все это вместе для вас. И это здорово, если вы имеете дело с совершенно новым приложением, которое использует только React и ничего больше. Вы можете написать какой-то компонент, и пока вы находитесь внутри части DOM, принадлежащей React, это так же просто, как разместить этот тег на странице, чтобы использовать ваш компонент.

Но как только вы берете эти компоненты и используете их вне React, все становится намного сложнее. Поскольку то, как компоненты React превращаются в теги, полностью выходит за рамки того, что предоставляют веб-стандарты, ничто иное, кроме React, не знает, как предоставить декларативный способ использования этих компонентов. Если я хочу поместить компоненты React в существующее представление Backbone, использующее шаблоны Handlebars, вы должны отобразить в шаблоне фиктивный элемент div с помощью класса или идентификатора, который вы можете использовать в качестве дескриптора, а затем написать императивный JavaScript, чтобы найти этот фиктивный элемент div и смонтировать его. ваш компонент в это. У вас есть приложение Express.js, которое использует шаблоны на стороне сервера? Ну, это та же самая песня и танец. Страница JSP? Вы смеетесь, но есть тонна приложений, все еще использующих их. Если вы не какой-то запуск без существующего кода, вы ' Нам придется написать некоторые материалы для повторного использования компонентов React во многих приложениях. Между тем, Polymer достигает компонентов с помощью стандарта веб-компонентов, и, используя спецификацию Custom Element, Polymer может создавать компоненты, которые браузер просто знает, как использовать. Я могу поместить компонент Polymer на страницу JSP, шаблон Express.js, представление ASP.NET, представление Backbone ... даже внутри компонента React. Буквально везде, где вы можете использовать HTML, вы можете использовать компонент Polymer. Люди, которые разрабатывают для повторного использования, обращаются к веб-стандартам, потому что стандарты - это контракт, который позволяет легко сделать вещи совместимыми друг с другом. YouTube продолжает создавать все больше и больше материалов в Polymer (источник: Polymer получает компоненты с помощью стандарта веб-компонентов, и, используя спецификацию Custom Element, Polymer может создавать компоненты, которые браузер просто знает, как использовать. Я могу поместить компонент Polymer на страницу JSP, шаблон Express.js, представление ASP.NET, представление Backbone ... даже внутри компонента React. Буквально везде, где вы можете использовать HTML, вы можете использовать компонент Polymer. Люди, которые разрабатывают для повторного использования, обращаются к веб-стандартам, потому что стандарты - это контракт, который позволяет легко сделать вещи совместимыми друг с другом. YouTube продолжает создавать все больше и больше материалов в Polymer (источник: Polymer получает компоненты с помощью стандарта веб-компонентов, и, используя спецификацию Custom Element, Polymer может создавать компоненты, которые браузер просто знает, как использовать. Я могу поместить компонент Polymer на страницу JSP, шаблон Express.js, представление ASP.NET, представление Backbone ... даже внутри компонента React. Буквально везде, где вы можете использовать HTML, вы можете использовать компонент Polymer. Люди, которые разрабатывают для повторного использования, обращаются к веб-стандартам, потому что стандарты - это контракт, который позволяет легко сделать вещи совместимыми друг с другом. YouTube продолжает создавать все больше и больше материалов в Polymer (источник: Я могу поместить компонент Polymer на страницу JSP, шаблон Express.js, представление ASP.NET, представление Backbone ... даже внутри компонента React. Буквально везде, где вы можете использовать HTML, вы можете использовать компонент Polymer. Люди, которые разрабатывают для повторного использования, обращаются к веб-стандартам, потому что стандарты - это контракт, который позволяет легко сделать вещи совместимыми друг с другом. YouTube продолжает создавать все больше и больше материалов в Polymer (источник: Я могу поместить компонент Polymer на страницу JSP, шаблон Express.js, представление ASP.NET, представление Backbone ... даже внутри компонента React. Буквально везде, где вы можете использовать HTML, вы можете использовать компонент Polymer. Люди, которые разрабатывают для повторного использования, обращаются к веб-стандартам, потому что стандарты - это контракт, который позволяет легко сделать вещи совместимыми друг с другом. YouTube продолжает создавать все больше и больше материалов в Polymer (источник:http://react-etc.net/entry/youtube-is-being-rebuilt-on-web-components-and-polymer ), и я могу только представить, что основанный на стандартах аспект Polymer является причиной этого. Этот проигрыватель YouTube в середине страницы YouTube можно превратить в компонент, который принимает источник контента в качестве свойства, и внезапно любой, кто хочет встроить проигрыватель YouTube в свою страницу, может буквально использовать тот же код проигрывателя, который использует YouTube. , и они могут сделать это, просто вставив тег на свою страницу.

Резюме

Я вижу, что сейчас определенно есть некоторые привлекательные аспекты React. Если все, что вы используете, это React, вы можете создавать некоторые виджеты и некоторые компоненты и декларативно использовать их повсеместно. Но я думаю, что для React было бы намного лучше, если бы он использовал некоторые из стандартов веб-компонентов для достижения своих целей, вместо того, чтобы уйти и создать браузер в браузере и сложный механизм для синхронизации всего.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.