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


521

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

Відповідно до цієї розмови про JSConf з ЄС та домашньої сторінки React, головними перевагами React є:

  • Розв'язка та збільшена згуртованість за допомогою складової моделі
  • Абстракція, композиція та експресивність
  • Віртуальні події DOM та синтетичні (що в основному означає, що вони повністю реалізували DOM та його систему подій)
    • Вмикає сучасні матеріали подій HTML5 в IE 8
    • Візуалізація на стороні сервера
    • Заповітність
    • Прив’язки до SVG, VML та <canvas>

Майже все, що згадується, інтегрується у веб-браузери на власній основі через веб-компоненти, крім цієї віртуальної концепції DOM (очевидно). Я можу побачити, як віртуальний DOM та синтетичні події сьогодні можуть бути корисними для підтримки старих браузерів, але чи не викидаєте величезний фрагмент коду рідного браузера, як, наприклад, зйомка себе в ногу в довгостроковій перспективі? Що стосується сучасних браузерів, чи не так багато непотрібних накладних витрат / винахід колеса?

Ось деякі речі, на які я думаю, що React не вистачає, щоб веб-компоненти подбали про вас. Виправте мене, якщо я помиляюся.

  • Підтримка власного браузера (читайте "гарантовано швидше")
  • Пишіть сценарій мовою сценаріїв, пишіть стилі мовою стилів, пишіть розмітку мовою розмітки.
  • Стиль капсулювання за допомогою Shadow DOM
    • Натомість React має це , для чого потрібно писати CSS в JavaScript. Не дуже.
  • Двостороння зв'язування

12
Wrt двостороння зв'язування. Ця функція є проблематичною в масштабі. У тривіальних випадках це працює добре, але в реальних випадках ти зазвичай виявляєш, що для збереження керованого коду потрібен модуль перегляду, а не прив’язка до фактичної моделі, що робить двосторонній зв'язок набагато менш корисним, ніж спочатку здавалося. Я думаю, що це може бути перевагою React у тому, що він не забезпечує двостороннє прив'язування, оскільки це змушує належну архітектуру потоку даних.
Joeri Sebrechts

8
Я подивився на React, Angular та Knockout. Я вважаю Нокаут найчистішим у плані поділу шаблонів, даних та прив’язки. Мені хотілося сподобатися реагувати, але намагаючись створити простий Combobox, я розумію, що я писав набагато більше коду і змішував логіку візуалізації з HTML-шаблоном. Мені здається, ці бібліотеки / apis рухають нас назад, а не вперед. Найкраще в React - це маніпуляція з віртуальним домом, але я можу побачити, що до інших встановлених рамок можна потрапити раніше, ніж пізніше.
mike01010

41
Я дуже здивований (і також радий!), Що це питання не було закрито як "в першу чергу на основі думки".
іконоборство

4
Неможливо написати "скрипт мовою сценаріїв" та "розмітку мовою розмітки", якщо ви робите шаблони будь-якого типу. Кутовий, полімерний тощо використовують шаблон DSL, вбудований у HTML. React використовує шаблон DSL, вбудований в JS (JSX). Проблема вбудовування DSL в HTML полягає в тому, як встановити область для отримання значень з JS. Це призводить до складної системи діапазону $ Angular. У JSX, з іншого боку, сфера змінних у шаблонах є просто сферою JS - я вважаю це набагато менш заплутаним.
Енді

3
На даний момент компоненти React (якщо погано написано) були б швидшими, ніж ті самі в будь-якій структурі, пов'язаній з DOM. Магія v-dom і відрізняється магія - це USP реагування. Моя думка - чому бровари не будували б подібне на своєму рідному наборі функцій. Що зупиняє їх, і якщо нічого не зупиняє їх, то, ймовірно, провід Реакту, ймовірно, буде короткочасним.
fasttrainofoughts

Відповіді:


664

Оновлення:  ця відповідь здається досить популярною, тому мені знадобилося трохи часу, щоб її трохи очистити, додати нову інформацію та уточнити кілька речей, які, на мою думку, були недостатньо зрозумілими. Будь ласка, прокоментуйте, якщо ви вважаєте, що щось інше потребує уточнення чи оновлення.

Більшість ваших занепокоєнь справді є питанням думки та особистих уподобань, але я постараюся відповісти максимально об'єктивно:

Рідний проти укладений

Пишіть JavaScript у ванільному 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, можуть бути "DSLs", які "вбудовуються" у два різні сенси, а взагалі не є "вбудованою 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, але вони лексично охоплюються чи динамічно охоплюються? Вони набираються статично чи динамічно? Сильно чи слабко? Що з числовими типами? Введіть коерсіон? Які значення є правдивими, а які - хибними? Чи можу я мати функції вищого порядку? Рекурсія? Хвостовий дзвінок? Лексичні закриття? Чи оцінюються вони у звичайному або додатковому порядку? Чи є ледача чи нетерпляча оцінка? Чи передаються аргументи функціям за значенням або посиланням? Вони змінюються? Незмінний? Наполегливі? Що з об’єктами? Заняття? Прототипи? Спадщина?

Це не тривіальні запитання, і все ж я мушу знати відповіді на них, якщо хочу зрозуміти код Сасса чи Менш. Я вже знаю ці відповіді на JavaScript, так що це означає, що я вже розумію всі внутрішні DSL (як стилі вбудованого в React) на цих самих рівнях, тому, якщо я використовую React, я повинен знати лише один набір відповідей на них (і багато подібних ) питання, тоді як коли я використовую напр. Тоді я повинен знати три набори цих відповідей і розуміти їх наслідки.

Це не означає, що так чи інакше завжди краще, але кожен раз, коли ви вводите іншу мову в суміш, тоді ви платите певну ціну, яка може бути не такою очевидною на перший погляд, і ця ціна є складністю.

Я сподіваюся, що я трохи уточнив, що я спочатку мав на увазі.

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

Двостороння зв'язування

Це дійсно цікавий предмет, а насправді також питання уподобань. Двосторонній не завжди краще, ніж односторонній. Це питання про те, як ви хочете моделювати стан змін у вашій програмі. Я завжди розглядав двосторонні прив'язки як ідею, яка дещо суперечить принципам функціонального програмування, але функціональне програмування - не єдина парадигма, яка працює, деякі люди вважають за краще такий тип поведінки, і обидва підходи, здається, працюють досить добре на практиці. Якщо вас цікавлять деталі дизайнерських рішень, пов’язаних із моделюванням штату в Реакті, тоді дивіться розмову Піта Ханта (пов’язану з цим питанням) та розмову Тома Окчіно та Джордана Уолке,  які дуже добре пояснюють це в моя думка.

Оновлення: Дивіться також ще одну розмову Піта Ханта: Будьте передбачувані, невірні: функціональне програмування DOM .

Оновлення 2: Варто відзначити, що багато розробників сперечаються проти двостороннього потоку даних або двостороннього прив'язки, деякі навіть називають це антидіаграмою. Візьмемо для прикладу архітектуру додатків Flux, яка явно уникає моделі MVC (яка виявилася складною для масштабних програм у Facebook та Instagram) на користь суворо однонаправленого потоку даних (див. Hacker Way: Переосмислення розробки веб-додатків у Facebook talk by Том Окчіно, Цзін Чен та Піт Хант для гарного вступу). Також багато критики проти AngularJS (найпопулярніша веб-рамка, яка грунтується на моделі MVC, відома двостороннім зв'язуванням даних), включає аргументи проти цього двостороннього потоку даних, див.

Оновлення 3: Ще одна цікава стаття, яка добре пояснює деякі проблеми, про які йшлося вище, - Деконструкція потоку ReactJS - Не використання MVC з ReactJS Мікаел Брассман, автор RefluxJS (проста бібліотека для однонаправленої архітектури прикладних потоків даних, натхненна Flux).

Оновлення 4: На даний момент Ember.js відходить від двостороннього прив'язки даних, а в майбутніх версіях це буде за замовчуванням односторонній. Дивіться: Розмова про майбутнє Ембер Стефана Пеннера з симпозіуму Ембергартен у Торонто 15 листопада 2014 року.

Оновлення 5: Дивіться також: Дорога до Ембер 2.0 RFC - цікава дискусія у запиті на виклик Тома Дейла :

"Коли ми розробили оригінальний шар шаблону, ми зрозуміли, що зробити прив'язку даних двостороннім не дуже шкідливо: якщо ви не встановите двосторонню прив'язку, це фактично одностороння прив'язка!

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

Крім того, спілкування між компонентами найчастіше виражається як події чи зворотні дзвінки . Це можливо в Ембер, але домінування двосторонніх зв'язків даних часто призводить людей до шляху використання двосторонніх прив'язок як каналу зв'язку . Досвідчені розробники Ембер (як правило) не роблять цієї помилки, але це зробити легко. " [Наголос додано]

Рідні проти В.М.

Підтримка власного браузера (читайте "гарантовано швидше")

Тепер нарешті щось, що не є питанням думки.

Насправді тут все навпаки. Звичайно, "рідний" код можна записати на C ++, але як ви думаєте, на чому написані двигуни JavaScript?

Насправді двигуни JavaScript справді вражають оптимізаціями, якими вони користуються сьогодні - і не тільки V8 більше, але SpiderMonkey і навіть Чакра сяє в наші дні. І майте на увазі, що з компіляторів JIT код не тільки настільний, наскільки це можливо, але є також можливості оптимізації часу роботи, які просто неможливо зробити в будь-якому статично складеному коді.

Коли люди думають, що JavaScript повільний, вони зазвичай мають на увазі JavaScript, який отримує доступ до DOM. DOM повільний. Це рідний текст, написаний на C ++, але все ж він повільний, як пекло через складність, яку він має реалізувати.

Відкрийте консоль і напишіть:

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

і подивіться, скільки властивостей divмає реалізувати порожній елемент, який навіть не приєднаний до DOM. Це лише  властивості першого рівня, які є "власними властивостями", тобто. не успадковані від прототипу ланцюга:

вирівнювати, onwaiting, onvolumechange, ontimeupdate, onsuspend, onsubmit, onstalled, OnShow, onselect, onseeking, onseeked, OnScroll, OnResize, OnReset, onratechange, OnProgress, onplaying, onplay, OnPause, OnMouseWheel, OnMouseUp, OnMouseOver, onmouseout, OnMouseMove, OnMouseLeave, onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, onemptied, ondurationchange, ondrop, ondragstart, ondragover, ondraterndra, ondragendra, ondraterndra oncontextmenu, OnClose, OnClick, OnChange, oncanplaythrough, oncanplay, OnCancel, ONBLUR, OnAbort, перевірка орфографії, isContentEditable, contentEditable, outerText, InnerText, Accesskey, прихований, webkitdropzone, перетягувати, TabIndex, реж, переклад, мови, назва, childElementCount, lastElementChild,firstElementChild, діти, nextElementSibling, попереднійElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onselectstart, onsearch, onpaste, oncut, oncopy, onbeforepaste, onbeforecut, onbeforext, sclesh, scll, sckll, sckll, webkit, webkit, webkit, webkit, webkit, webkit, webkit, webkit, webkit, webkit, webkit, sckll, sckll, webkit, sckll, webkit, sckll, webkit, sckll, webkit, sckll, webkit, sckll, webkit, sckst clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, префікс, простір іменURI, id, стиль, атрибути, тегName, parentElement, textContent, baseURI, ownerDocument, nextSiblingC lasth, firstSiblingC lasth, firstsiildCild, lastHiildCild parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, набір даних, classList, className, externalHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offseteset, offset, offset, offset, offset, offset, offset простір іменURI, id, стиль, атрибути, tagName, parentElement, textContent, baseURI, ownerDocument, nextSibling, previousSibling, lastChild, firstChild, childNodes, parentNode, nodeType, nodeValue, nodeNameoncopy, onbeforepaste, onbeforecut, onbeforecopy, webkitShadowRoot, набір даних, classList, className, externalHTML, innerHTML, scrollHeight, scrollWidth, scrollTop, scrollLeft, clientHeight, clientWidth, clientTop, clientLeft, offseteset, offset, offset, offset, offset, offset, offset простір іменURI, 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 власності на кожному окремому вузлі сну? Це помилка? Ні, це лише застаріла версія традиційної події DOM рівня 0 одного з обробників подій, "яка повинна підтримуватися всіма елементами HTML , як атрибутами вмісту, так і атрибутами IDL" [наголос додано] в Розділі 6.1.6.2 специфікації HTML від W3C - не обійти.

Тим часом, це властивості першого рівня фальшивої DOM divв React:

реквізит, _власник, _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, використовує Facebook React для кращої продуктивності, хоча згідно Вікіпедії "Atom заснований на Chromium та написаний на C ++", тому він має повний контроль над нативної реалізації C ++ DOM (див. «Ядро Атома» ) та гарантовано матиме підтримку веб-компонентів, оскільки вона постачається разом із власним веб-браузером. Це лише нещодавній приклад проекту в реальному світі, який міг би використовувати будь-який інший тип оптимізації, як правило, недоступний для веб-додатків, але все ж він вирішив використовувати React, який сам написаний на JavaScript, для досягнення найкращої продуктивності, хоча Atom не було побудовано з React для початку, тож це не було дрібницею.

Оновлення 2

Існує цікаве порівняння Todd Parker, використовуючи WebPagetest для порівняння продуктивності прикладів TodoMVC, написаних у Angular, Backbone, Ember, Polymer, CanJS, YUI, Knockout, React та Shoestring. Це найбільш об'єктивне порівняння, яке я бачив досі. Тут важливо те, що всі відповідні приклади були написані експертами у всіх цих рамках, всі вони доступні на GitHub і їх можна вдосконалити будь-хто, хто думає, що деякий код можна оптимізувати для швидшого запуску.

Оновлення 3

У наступних версіях Ember.js буде включати ряд особливостей React, про які йдеться тут (включаючи віртуальний DOM та односпрямоване прив'язування даних, якщо назвати лише декілька), що означає, що ідеї, що виникли в React, вже мігрують в інші рамки. Див.: Дорога до Ембер 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? Питання в тому, чи буде мій додаток швидким із фреймворком X. "

У своїй відповіді 2011 року на те: Які емпіричні технічні причини не використовувати jQuery, я пояснюю подібну проблему, що неможливо написати портативний DOM-маніпуляційний код без бібліотеки, як jQuery, але що люди рідко роблять це.

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

Оновлення 5

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

Дякую Кевіну Лозанд'є за те, що він звернув це до мене .


75
саме так я називаю вичерпну відповідь, дякую!
Demwunz

14
Схоже, Atom віддаляється від React. Див. Github.com/atom/atom/isissue/3677 .
Juho Vepsäläinen

6
@ash: Якщо ви читаєте далі по темі, вони говорять про те, як вони хотіли б врешті-решт повністю відійти від React та інших фреймворків, а просто скочуйте свої власні, використовуючи власні елементи та тінь DOM.
musicfreak

3
Тільки для уточнення формулювання вище, у списку @ErikAllik, FRP (функціональне реактивне програмування) - це не нова мова, а скоріше підхід, що набирає популярності. Насправді, "Elm заснований на ідеї функціонального реактивного програмування" (від elm-lang.org), і, як він згадував, існують рамки FRP для Haskell тощо.
Джон Кумбс

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

16

Полімер - приголомшливий. Реакція є приголомшливою. Вони не одне і те ж.

Полімер - це бібліотека для побудови сумісних веб-компонентів.

Реакція - це V в MVC. Це Погляд, і більше нічого. Принаймні, само собою.

Реакція не є рамкою.

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

Існує багато технологій, моделей та архітектурних стилів, за якими реагують розробники, але реагувати саме по собі не є рамкою.

Сумно, що ніхто не знайшов час сказати найпростішу можливу річ, що їх не можна порівнювати. Вони мають деяке перекриття, але вони більше відрізняються від однакових.

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


Чи не реагує і M, і V, не тільки V, оскільки він зберігає та оновлює стан даних і надає фрагменти html за допомогою компонентів?
абеліто

1
Існують бібліотеки управління державою реагування, такі як флюс або редукс, але вони не упаковані в реакцію.
Робоцусі

О, я бачу, ми не вважаємо, що дані Перегляду є модельними даними .., поки вони не будуть представлені на стороні сервера. Навіть незважаючи на те, що React містить стан компонента (перегляд даних), дані залишаються до подання. Що має сенс.
абеліто

15

Хлопці React мають досить хороше пояснення щодо порівняння між React та Web Components:

Намагання порівнювати та протиставляти Реагування з WebComponents неминуче призводить до чудових висновків, оскільки дві бібліотеки створені для вирішення різних проблем. WebComponents забезпечують сильну інкапсуляцію для багаторазових компонентів, тоді як React надає декларативну бібліотеку, яка підтримує DOM у синхронізації з вашими даними. Дві цілі є взаємодоповнюючими; інженери можуть поєднувати та узгоджувати технології. Як розробник, ви можете використовувати React у своїх WebComponents або використовувати WebComponents в React або те й інше.


14

Ще одна відповідь в одному пункті конкретно:

Пишіть JavaScript у ванільному JavaScript, пишете CSS у CSS, пишете HTML у HTML.

Ніщо не заважає вам писати Javascript у, скажімо, CoffeeScript, TypeScript, ClojureScript або що-небудь інше. Це суто питання переваги.

HTML - найкращий DSL для статичних документів HTML. Але це не забезпечує нічого для динамічного HTML. І у веб-переглядачі найкраща мова, що робить HTML динамічним, - це Javascript, а не чистий HTML із спеціальними маніпуляціями з DOM Javascript або мовою шаблонів, як рулі, які не мають навіть половини мови.

Для CSS, якщо ваш CSS статичний, ви пишете його як завжди. Якщо вона повинна бути динамічною на основі деяких значень часу виконання, це та сама історія, що і HTML: Javascript - найкращий спосіб зробити її динамічною.


1
Я ціную відповідь, але це насправді не було моєю суттю. Сподіваюся, мої зміни зробили це питання трохи зрозумілішим?
CletusW

1
Вибачте, це не так. Ви все ще можете написати свій стиль будь-якою мовою стилів в окремому файлі. І JSX React робить так, що ви використовуєте мову розмітки.
DjebbZ

3
"Javascript - найкращий спосіб зробити [CSS] динамічним" - просто кажучи, він насправді не пояснює, чому.
pilau

1
Добре, якщо стилі / класи потрібно змінювати відповідно до введення користувачем або діловими правилами, просто використовуйте javascript, щоб змінити їх. У vanilla js ви маніпулюєте властивостями classList або стилів вузла 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 .
limscoder

4
Нічого, ти правий! Я думаю, вони просто хотіли приклад автоматичного пошуку вузла. Це, мабуть, не найкраще, що можна дати.
CletusW

6

Я думаю, що найбільший недолік React, на мою думку, полягає в тому, що він не заснований на веб-стандартах. Зараз React - це дуже потужний інструмент, але оскільки він обходить стільки того, що надає браузер, коли це можливо, рішення, яке, здавалося б, має сенс зараз, швидше за все, не матиме сенсу через кілька років, оскільки вбудовані засоби браузерів продовжують покращити. Тому я хотів би поговорити про це і про те, як це впливає на кілька різних аспектів веб-додатків.

Продуктивність

Люди люблять стверджувати, що перевага React полягає в тому, що він повністю реінвестує всю модель DOM та події, а існуючий стандартний DOM є важким і дорогим і що ні, але наприкінці дня я не знайшов ефективності Реагуйте, щоб бути кращим, ніж те, що я можу вийти з добре написаної програми "Магістраль" або "Полімер". Насправді в більшості мого професійного досвіду ефективність React насправді була дещо гіршою. Це не означає, що Реакція повільна ... Це просто вибір кращого кровотоку, про який ми всі думали, перш ніж взяти на себе руки.

У відповіді rsp він вказує, що модель DOM React для діва набагато легша за вагу, ніж рідний DOM, і це, безумовно, правда. Однак, щоб React був корисним, цей "віртуальний" дів в кінцевому підсумку повинен стати справжнім дівом. Тож у моєму світогляді справа не в тому, щоб ділитися "Реакт" проти "рідним дівом". Це Div React + рідний div проти просто рідний div. Накладні витрати на версію DOM React нетривіальні, і якщо стандарти коли-небудь скидають деякі з цих непотрібних атрибутів і дозволяють рідним вузлам DOM бути набагато легшими, раптом цей наклад здасться справді дорогим.

В одному з моїх попередніх місць роботи ми мали кілька заявок в «Полімері», а деякі - в «Реакт». Одне з ранніх полімерних застосунків переписалось на React, тому що компанія мала стандарт, і на підставі вимірювань я взяв React версію цього ж додатка, що завершився, використовуючи приблизно на 30% більше пам'яті, ніж версія Polymer. , і хоча різниця була незначною, полімерна версія також була надана за менший час. Тут слід врахувати одне, що ми говоримо про програми, написані людьми, і люди не є ідеальними, тому можливо, що реалізація цієї програми не використала б усе, на що React здатний. Але я думаю, що принаймні деякі стосунки пов'язані з накладними реакторами, пов'язаними з тим, що є власна версія DOM.

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

Оновлення для продуктивності: Одна з бібліотек, на яку я натрапила деякий час, робить те, що, на мою думку, є кращим завданням управління оновленнями до DOM. Це Бібліотека інкрементальних домів Google, і я вважаю, що той факт, що він працює з домом на місці і не повинен створювати "віртуальну копію", є набагато більш чистим підходом із значно меншими витратами на пам'ять. Детальніше тут: http://google.github.io/incremental-dom/#about

Декларативні та імперативні компоненти

Одна з речей, яку ви завжди чуєте, коли ви говорите про компонентне додаток, - це всі переваги того, що ваші компоненти є декларативними. Всередині світогляду Реакта все є приємним та декларативним. Ви пишете JavaScript, який повертає розмітку, і React склеює все це для вас. І це чудово, якщо ви маєте справу з абсолютно новим додатком, який використовує лише React та більше нічого. Ви можете написати якийсь компонент, і поки ви знаходитесь у фрагменті DOM, що належить React, це так просто, як розмістити цей тег на сторінці, щоб споживати ваш компонент.

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

Підсумок

Я можу бачити, що зараз точно є деякі привабливі аспекти Реагувати. Якщо ви використовуєте лише React, ви можете створити деякі віджети та деякі компоненти та декларативно повторно використовувати їх у всьому місці. Але я думаю, що React було б набагато краще, якби він використовував деякі стандарти веб-компонентів, щоб досягти того, що робить, замість того, щоб вимикатись і створювати браузер у браузері та складний механізм, щоб все синхронізувати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.