Facebook의 React와 웹 구성 요소의 장단점 (폴리머)


521

다가오는 웹 구성 요소 사양에 비해 Facebook의 React 의 주요 이점은 무엇입니까 (또는 그 반대) (또는 더 많은 애플 대 애플 비교는 Google의 폴리머 라이브러리 와 비교할 수 있습니다 )?

이 JSConf EU 대화 및 React 홈페이지 에 따르면 React의 주요 이점은 다음과 같습니다.

  • 구성 요소 모델을 사용하여 분리 및 응집력 향상
  • 추상화, 구성 및 표현력
  • 가상 DOM 및 합성 이벤트 (기본적으로 DOM 및 해당 이벤트 시스템을 완전히 다시 구현했음을 의미)
    • IE 8에서 최신 HTML5 이벤트를 지원합니다.
    • 서버 측 렌더링
    • 테스트 가능성
    • SVG, VML 및 <canvas>

언급 된 거의 모든 것은이 가상 DOM 개념을 제외하고 웹 구성 요소를 통해 기본적으로 브라우저에 통합되고 있습니다. 가상 DOM 및 가상 이벤트가 오늘날 오래된 브라우저를 지원하는 데 도움이되는 방법을 알 수 있지만 장기적으로 발을 내딛는 것과 같은 거대한 기본 브라우저 코드를 버리지는 않습니까? 최신 브라우저에 관한 한, 휠의 불필요한 오버 헤드 / 재발견이 많지 않습니까?

여기에 내가 몇 가지 있습니다 생각 웹 구성 요소가 당신을 위해 돌볼 것없는 반응은. 틀린 점 있으면 지적 해주세요.

  • 기본 브라우저 지원 ( "더 빠른 것으로 보장"참조)
  • 스크립트 언어로 스크립트 작성, 스타일 언어로 스타일 작성, 마크 업 언어로 마크 업 작성.
  • Shadow DOM을 사용한 스타일 캡슐화
    • 반응 대신이 자바 스크립트로 CSS를 작성 요구하는. 예쁘지 않은.
  • 양방향 바인딩

12
Wrt. 양방향 바인딩. 이 기능은 규모에 문제가 있습니다. 사소한 경우에는 잘 작동하지만 실제 사례에서는 일반적으로 코드를 관리 가능하게 유지하려면 실제 모델에 바인딩하는 대신 뷰 모델에 바인딩해야하므로 양방향 바인딩보다 유용하지 않습니다. 처음에는 보였다. 적절한 데이터 흐름 아키텍처를 강제하기 때문에 양방향 바인딩을 제공하지 않는다는 것이 React의 이점이라고 생각합니다.
Joeri Sebrechts

8
나는 React, Angular 및 Knockout을 보았습니다. UI 템플릿, 데이터 및 바인딩의 분리 측면에서 녹아웃이 가장 깨끗합니다. 나는 반응을 좋아하고 싶었지만 간단한 콤보 박스를 만들려고 노력했다. 나는 더 많은 코드를 작성하고 html templating과 렌더링 로직을 혼합하고 있음을 알았다. html / jina2와 같은 것을 사용하여보다 훨씬 더. 이 라이브러리 / API는 우리를 앞으로가 아니라 뒤로 이동시킵니다. React의 가장 좋은 점은 가상 돔 조작이지만, 다른 프레임 워크가 조만간 등장한다는 것을 알 수 있습니다.
mike01010

41
이 질문이 "주로 의견 기반"으로 종료되지 않았다는 사실에 매우 놀랐습니다.
iconoclast

4
템플릿을 사용하는 경우 "스크립트 언어로 스크립트"및 "마크 업 언어로 마크 업"을 작성할 수 없습니다. 각도, 폴리머 등은 HTML에 포함 된 템플릿 DSL을 사용합니다. React는 JS (JSX)에 포함 된 템플릿 DSL을 사용합니다. HTML에 DSL을 포함시키는 문제는 JS로부터 값을 얻는 범위를 설정하는 방법입니다. 이것은 Angular의 복잡한 $ scope 시스템으로 이어집니다. 반면에 JSX에서는 템플릿의 변수 범위가 JS 범위에 불과합니다. 혼란스럽지 않습니다.
Andy

3
현재 React 구성 요소 (잘못 작성되지 않은 경우)는 DOM 바인딩 프레임 워크에서보다 빠릅니다. v-dom과 diff-ing 마술은 반응의 USP입니다. 내 요점은-왜 브라우저가 기본 기능 세트와 같은 차이점을 만들지 않을 것입니까? 그것들을 멈추게하고, 아무것도 멈추지 않으면 (그들을 막 으면) React의 리드는 아마도 수명이 짧아 질 것입니다.
fasttrainofthoughts

답변:


664

업데이트 :  이 답변은 꽤 인기있는 것으로 보이므로 약간 정리하고 새로운 정보를 추가하고 충분히 명확하지 않은 것으로 생각되는 몇 가지를 명확히하는 데 시간이 걸렸습니다. 다른 설명이나 업데이트가 필요하다고 생각되면 의견을 말하십시오.

대부분의 우려 사항은 실제로 의견과 개인적 선호의 문제이지만 가능한 한 객관적으로 답변하려고 노력할 것입니다.

네이티브 대 컴파일

바닐라 JavaScript로 JavaScript 작성, CSS로 CSS 작성, HTML로 HTML 작성

위로 하루에 하나 작성해야하는지 여부 뜨거운 논쟁이 있었다 네이티브  손으로 조립 또는 컴파일러가 당신을 위해 어셈블리 코드를 생성하기 위해 C와 같은 높은 수준의 언어를 사용. 그 전에도 사람들은 어셈블러 에 대한 신뢰를 거부 하고 손으로 네이티브 머신 코드 를 작성하는 것을 선호했습니다 ( 그리고 나는 농담하지 않습니다 ).

한편, 오늘 HTML 쓰기 많은 사람들이 있습니다 HAML 또는 에 CSS를 말대꾸 또는 이하 에서 자바 스크립트 커피 스크립트 또는 타이프 라이터가 . 저기에있어. 효과가있다. 어떤 사람들은 그것을 선호하지만 어떤 사람들은 그렇지 않습니다.

요점은 바닐라 JavaScript로 JavaScript를 작성 하지 않고 CSS로 CSS를 HTML로 HTML을 작성하는 데 근본적으로 잘못된 것이 없다는 것입니다 . 그것은 실제로 선호의 문제입니다.

내부 및 외부 DSL

 대신 Shadow DOM React를 사용하는 스타일 캡슐화에는 JavaScript로 CSS를 작성해야합니다. 예쁘지 않은.

예쁘거나 말끔하게 표현 적입니다. JavaScript는 매우 강력한 언어로 CSS보다 훨씬 강력합니다 (CSS 전 처리기 포함). 그것은 일종의 내부 또는 외부 DSL을 선호하는지에 달려 있습니다. 다시, 선호의 문제.

(참고 : 원래 질문에서 참조 된 React인라인 스타일에 대해 이야기했습니다 .)

DSL의 종류-설명

업데이트 : 답변을 작성한 후 얼마 후에 답변을 읽으면 여기서 의미하는 바를 설명해야한다고 생각합니다. DSL은 도메인 별 언어 이며 내부적이거나 (예 : JavaScript와 같은 호스트 언어의 구문을 사용하여 (예 : JSX가없는 React 또는 위에서 언급 한 React의 인라인 스타일과 같이)) 외부에있을 수 있습니다 (다른 구문을 사용) 이 예에서와 같이 호스트 언어보다 JavaScript 내에서 CSS (외부 DSL)를 인라인하는 것입니다.

일부 문헌에서는 이러한 종류의 DSL을 설명하기 위해 "내부"및 "외부"와 다른 용어를 사용하기 때문에 혼동 될 수 있습니다. 때때로 "내장"대신 "내장"이 사용되지만 "내장"이라는 단어는 다른 것을 의미 할 수 있습니다. 예를 들어 Lua 내장 (내장) DSL과 관련이없는 "루아 : 확장 가능한 내장 언어"로 설명 됩니다. 외부 DSL과 반대되는 개념이지만 SQLite가 내장 데이터베이스와 같은 의미로 내장되어 있음을 의미합니다. "e"가 세 번째 의미에서 "내장 된"을 의미하는 eLua 도 있습니다. 임베디드 시스템을 의미 합니다.! eLua와 같은 것은 "내장 된 DSL"이 아닌 두 가지 다른 의미로 "내장 된" "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>

첫 번째 예는 질문에서 "JavaScript로 CSS 작성. 예쁘지 않다"라는 설명을 사용합니다. 두 번째 예는 Sass를 사용합니다. CSS를 작성하기 위해 JavaScript를 사용하는 것은 ( "pretty"의 일부 정의에는) 좋지 않을 수 있지만 동의하면 한 가지 이점이 있습니다.

Sass에서 변수와 함수를 사용할 수 있지만 어휘 범위 또는 동적 범위가 있습니까? 정적으로 또는 동적으로 입력됩니까? 강하거나 약합니까? 숫자 형은 어떻습니까? 유형 강제? 어느 값이 진실하고 어떤 값이 거짓입니까? 고차 함수를 가질 수 있습니까? 재귀? 테일 전화? 어휘 폐쇄? 정상 순서 또는 적용 순서로 평가됩니까? 게 으르거나 열심 인 평가가 있습니까? 함수에 대한 인수가 값 또는 참조로 전달됩니까? 그들은 변할 수 있습니까? 불변? 지속성 있는? 객체는 어떻습니까? 클래스? 프로토 타입? 계승?

사소한 질문은 아니지만 Sass 또는 Less 코드를 이해하려면 답변을 알아야합니다. 나는 이미 JavaScript에 대한 답변을 알고 있으므로 React의 인라인 스타일과 같은 모든 내부 DSL을 이미 이해하고 있음을 의미하므로 React를 사용하면 그에 대한 답변 세트를 하나만 알아야합니다. ) 질문, 예를 들어 사용할 때 Sass와 Handlebars는 그런 세 가지 답변을 알고 그 의미를 이해해야합니다.

한 가지 또는 다른 방법이 항상 더 좋다고 말할 수는 없지만 다른 언어를 믹스에 도입 할 때마다 언뜻보기에는 분명하지 않을 수도있는 가격을 지불합니다.이 가격은 복잡합니다.

내가 원래 의미 한 바를 명확히했으면합니다.

데이터 바인딩

양방향 바인딩

이것은 정말 흥미로운 주제이며 실제로 선호도의 문제입니다. 양방향이 항상 단방향보다 낫지는 않습니다. 응용 프로그램에서 변경 가능한 상태를 모델링하려는 방법에 대한 질문입니다. 나는 항상 양방향 바인딩을 함수형 프로그래밍의 원칙에 다소 반대되는 생각으로 보았지만 함수형 프로그래밍은 작동하는 유일한 패러다임이 아니며 일부 사람들은 이런 종류의 행동을 선호하며 두 가지 접근 방식은 실제로는 잘 작동하는 것처럼 보입니다. React에서 상태 모델링과 관련된 디자인 결정의 세부 사항에 관심이 있다면 Pete Hunt (질문에 링크 됨)와 Tom Occhino와 Jordan Walke의 이야기를  잘 살펴보십시오. 내 의견.

업데이트 : Pete Hunt의 또 다른 이야기를 참조하십시오 : 예측 가능하고 정확하지 않습니다 : 기능적 DOM 프로그래밍 .

업데이트 2 : 많은 개발자들이 양방향 데이터 흐름 또는 양방향 바인딩 에 대해 논쟁 하고 있으며 일부는 반 패턴이라고도합니다. 예를 들어 가지고 플럭스 명시 적으로 방지 응용 프로그램 아키텍처 MVC의 엄격 단방향 데이터 흐름에 찬성 (대형 페이스 북과 인스 타 그램 애플리케이션을위한 확장하기 어려운 것으로 판명) 모델을합니다 (참조 페이스 북에 다시 생각 웹 응용 프로그램 개발 : 해커 웨이 에 의해 이야기 Tom Occhino, Jing Chen 및 Pete Hunt가 소개합니다. 또한 AngularJS 에 대한 많은 비판 (양방향 데이터 바인딩으로 알려진 MVC 모델을 기반으로 느슨하게 사용되는 가장 널리 사용되는 웹 프레임 워크)에는 해당 양방향 데이터 흐름에 대한 인수가 포함됩니다.

업데이트 3 : 위에서 논의 된 몇 가지 문제를 잘 설명하는 또 다른 흥미로운 기사는 ReactJS의 플럭스 분해-RefluxJS (Flux에서 영감을 얻은 단방향 데이터 흐름 응용 프로그램 아키텍처를위한 간단한 라이브러리)의 저자 Mikael Brassman의 ReactJS 와 함께 MVC를 사용하지 않음 입니다.

업데이트 4 : Ember.js 는 현재 양방향 데이터 바인딩에서 벗어나고 있으며 향후 버전에서는 기본적으로 단방향입니다. 참조 : 2014 년 11 월 15 일 토론토의 엠 베르 가르 텐 심포지엄에서 Stefan Penner 의 Ember 미래 이야기.

업데이트 5 : 참조 : The Road to Ember 2.0 RFC-Tom Dale의 풀 요청에 대한 흥미로운 토론 :

"원래 템플릿 레이어를 설계 할 때 모든 데이터 바인딩을 양방향으로 만드는 것은 그리 해롭지 않은 것으로 나타났습니다. 양방향 바인딩을 설정하지 않으면 사실상 일방적 인 바인딩입니다!

우리는 이후 React의 친구들의 도움을 받아 구성 요소가 변덕스러운 돌연변이를 경계하지 않고도 자녀에게 데이터를 전달할 수 있기를 원한다는 것을 깨달았습니다.

또한 구성 요소 간 통신은 가장 자연스럽게 이벤트 또는 콜백으로 표현됩니다 . 이것은 Ember에서 가능하지만 양방향 데이터 바인딩의 우세는 종종 사람들이 양방향 바인딩을 통신 채널로 사용하는 길을 안내합니다 . 숙련 된 Ember 개발자는 (보통)이 실수를하지는 않지만 쉽게 만들 수 있습니다. " [강조 추가]

기본 대 VM

기본 브라우저 지원 ( "더 빠른 것으로 보장"참조)

이제 마지막으로 의견이 아닌 무언가.

실제로 여기는 정확히 다른 방법입니다. 물론 "네이티브"코드는 C ++로 작성 될 수 있지만 JavaScript 엔진이 작성되었다고 생각하십니까?

사실 JavaScript 엔진은 오늘날 사용하는 최적화에서 정말 놀랍습니다 .V8뿐만 아니라 SpiderMonkey와 Chakra도 요즘 빛납니다. 그리고 JIT 컴파일러를 사용하면 코드가 가능한 한 기본적 일뿐만 아니라 정적으로 컴파일 된 코드에서는 수행 할 수없는 런타임 최적화 기회도 있습니다.

사람들은 JavaScript가 느리다고 생각할 때 일반적으로 DOM에 액세스하는 JavaScript를 의미합니다. DOM이 느립니다. C ++로 작성된 네이티브이지만 구현해야하는 복잡성 때문에 지옥만큼 느립니다.

콘솔을 열고 다음을 작성하십시오.

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

divDOM에 연결되지 않은 빈 요소가 구현해야하는 속성의 수를 확인하십시오 . 이것들은  "자신의 속성"인 첫 번째 레벨 속성입니다. 프로토 타입 체인에서 상속되지 않음 :

정렬, 대기 중, 볼륨 변경, 정시 업데이트, 일시 중단, 제출, 정지, 진행 중, 선택, 조회, 탐색, 진행 중, onresize, onreset, onratechange, 진행 중, 진행 중, 진행 중, 진행 중, onmousewheel, onmouseup, onmouseover, onmouseout, onmouseout, onmouseout, onmouseout onmouseenter, onmousedown, onloadstart, onloadedmetadata, onloadeddata, onload, onkeyup, onkeypress, onkeydown, oninvalid, oninput, onfocus, onerror, onended, onemptied, ondurationchange, ondrop, ondragstart, ondragover, ondragleave, ondragenter, ondragend, ondragend, ondragend, ondragend, ondragend, ondragend, ondragend, ondragend, ondragend, ondragend, ondragentd, ondragend, ondragentd, ondragend, ondragentd, ondragend, ondragentd, ondragentd, ondragend, ondragentd, ondragend, ondragend, ondragentd, ondragend, ondragentd, ondragentd, ondragend, ondragentd, ondragend oncontextmenu, onclose, onclick, onchange, oncanplaythrough, oncanplay, oncancel, onblur, onabort, 맞춤법 검사, isContentEditable, contentEditable, outerText, innerText, accessKey, hidden, webkitdropzone, 드래그 가능, tabIndex, dir, 번역, lang, title, childElementCount, lastElementChild,firstElementChild, children, nextElementSibling, previousElementSibling, onwheel, onwebkitfullscreenerror, onwebkitfullscreenchange, onselectstart, onsearch, onpaste, oncut, oncopy, onforeforee, onbeforecut, onbeforecopy, webkitShadowRoot, 데이터 세트, classList, className, outerHTML, innerHTML, scrollHeight, scrollWidth, scrollWidth, 스크롤 바퀴 clientHeight, clientWidth, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName, prefix, namespaceURI, id, style, attributes, 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, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName 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, clientTop, clientLeft, offsetParent, offsetHeight, offsetWidth, offsetTop, offsetLeft, localName 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브라우저에서 빈 네이티브의 두 번째 수준 (자체) 속성을 보려면 이 바이올린을 참조하십시오 .

진심으로, 모든 단일 div 노드 에서 onvolumechange 속성을 의미 합니까? 실수입니까? 아니, 그것은 " 컨텐츠 속성과 IDL 속성 둘 다로서 모든 HTML 요소에 의해 지원 되어야 한다 "[강조된 HTML 스펙 6.1.6.2 ] 의 이벤트 핸들러 중 하나의 레거시 DOM 레벨 0 전통적인 이벤트 모델 버전 일 뿐이다. W3C에 의해-그 주위에 방법이 없습니다.

한편, 이들은 divReact에서 가짜 DOM의 첫 번째 레벨 속성입니다 .

props, _owner, _lifeCycleState, _pendingProps, _pendingCallbacks, _pendingOwner

큰 차이가 있지 않습니까? 실제로 이것은 JSON ( LIVE DEMO )으로 직렬화 된 전체 객체입니다 . 왜냐하면  원형 참조를 포함하지 않기 때문에 실제로 JSON으로 직렬화 할 있기 때문 입니다. 원래 DOM의 세계에서는 상상할 수없는 ( 예외가 발생합니다) ) :

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

이것이 React가 네이티브 브라우저 DOM보다 빠를 수있는 주된 이유입니다. 왜냐하면 이 혼란 을 구현할 필요가 없기 때문 입니다.

참조 스티븐 Luscher하여이 프리젠 테이션은 C ++로 작성된 기본 DOM 또는 자바 스크립트로 작성 가짜 DOM : 빨리가 무엇인지 볼 수 있습니다. 매우 공정하고 재미있는 프레젠테이션입니다.

업데이트 : 향후 버전의 Ember.js 는 React에서 크게 영감을 얻은 가상 DOM을 사용하여 성능을 향상시킵니다. 참조 : 2014 년 11 월 15 일 토론토의 엠 베르 가르 텐 심포지엄에서 Stefan Penner 의 Ember 미래 이야기.

요약하자면 템플릿, 데이터 바인딩 또는 사용자 지정 요소와 같은 웹 구성 요소의 기능은 React에 비해 많은 이점이 있지만 문서 개체 모델 자체가 크게 단순화 될 때까지 성능이 그 중 하나가 아닙니다.

최신 정보

이 답변을 게시 한 지 두 달이 지났는데 여기에 관련된 뉴스가있었습니다. 방금 트위터에 글을 썼 듯이 JavaScript에서 GitHub가 작성한 Atom 텍스트 편집기 의 최신 버전 은 Facebook의 React를 사용 하여 Wikipedia에 따르면 "Atom은 Chromium을 기반으로하고 C ++로 작성되었습니다"라는 내용 에도 불구하고 더 나은 성능을 얻 습니다. 네이티브 C ++ DOM 구현 (참조 원자의 핵을 )  자체 웹 브라우저와 함께 제공되므로 웹 구성 요소를 지원합니다. 웹 애플리케이션에서는 일반적으로 사용할 수없는 다른 종류의 최적화를 사용할 수 있었지만 Atom을 통해도 최고의 성능을 달성하기 위해 JavaScript로 작성된 React를 사용하기로 선택한 실제 프로젝트의 최신 예일뿐입니다. React로 시작하지는 않았으므로 사소한 변경은 아닙니다.

업데이트 2

토드 파커 흥미로운 비교 하여 WebPagetest을 의 성능을 비교하기 위해 TodoMVC의 각도, 백본 작성 예, 엠버, 폴리머, CanJS은, YUI, 마네는 반응 신발 끈. 이것은 내가 지금까지 본 가장 객관적인 비교입니다. 여기서 중요한 것은 모든 해당 예제가 모든 해당 프레임 워크의 전문가에 의해 작성되었으며 모두 GitHub 에서 사용할 수 있으며 일부 코드가 더 빨리 실행되도록 최적화 될 수 있다고 생각하는 사람이라면 누구나 향상시킬 수 있다는 것입니다.

업데이트 3

향후 버전의 Ember.js 에는 여기에서 논의되는 많은 React 기능 (가상 DOM 및 단방향 데이터 바인딩 포함)이 포함되어 React에서 시작된 아이디어가 이미 다른 프레임 워크로 마이그레이션되고 있음을 의미합니다. 참조 : The Road to Ember 2.0 RFC – Tom Dale의 풀 요청에 대한 흥미로운 토론 (시작 날짜 : 2014-12-03) : "Ember 2.0에서는"가상 DOM "및 데이터 흐름 모델을 채택 할 것입니다. "React의 최고의 아이디어로 부품 간의 커뮤니케이션을 단순화합니다."

또한 Angular.js 2.0 은 여기서 논의 된 많은 개념을 구현하고 있습니다.

업데이트 4

Igwe Kalu의 의견에 답하기 위해 몇 가지 문제를 자세히 설명해야합니다.

"React가 궁극적으로 일반 JavaScript로 감소 할 때 React (JSX 또는 컴파일 출력)를 일반 JavaScript와 비교하는 것은 합리적이지 않습니다. [...] React를 사용하지 않고 React를 적용 할 수있는 전략 React는 DOM 삽입에 사용할 수 있습니다. 편의성 이외의 문제를 고려할 때 특별한 이점이 없습니다. " (전체 의견은 여기에 )

그것이 명확하지 않은 경우, 내 대답의 일부로 네이티브 DOM (브라우저에서 호스트 객체로 구현)과 React의 가짜 / 가상 DOM (JavaScript로 구현)에서 직접 작동하는 성능을 비교하고 있습니다 . 내가 만들려고했던 점은 자바 스크립트로 구현 된 가상 DOM이 있다는 것입니다 수 있습니다 C ++에서 구현 된 실제 DOM을 능가하고 있지 그 (그것 때문에 분명 많은 이해가되지 것입니다 자바 스크립트를 능가 할 수 반작용 되는 자바 스크립트로 작성)를. 필자의 요점은 "네이티브"C ++ 코드가 "네이티브가 아닌"JavaScript보다 항상 빠르다는 보장은 없다. 요점을 설명하기 위해 React를 사용하는 것은 단지 예일뿐입니다.

그러나이 의견은 흥미로운 문제에 영향을 미쳤다. 어떤 의미에서든 성능, 이식성, 기능과 같은 어떤 이유로 든 프레임 워크 (React, Angular 또는 jQuery)가 필요하지 않다는 것은 사실입니다. 프레임 워크가 항상 자신을 위해하는 일을 다시 만들고 바퀴를 재발 명 할 수 있기 때문입니다. 즉, 비용을 정당화 할 수 있습니다.

그러나 데이브 스미스는 웹 프레임 워크 성능을 비교할 때 요점을 놓치는 방법에 대해 잘 설명했다 . "두 웹 프레임 워크를 비교할 때 문제는 내 앱이 프레임 워크 X로 빠를 없다는 입니다. 문제는 내 앱이 프레임 워크로 빠를 것입니다. 엑스."

내 2011 대답 : jQuery를 사용하지 않는 몇 가지 경험적 기술적 인 이유가 무엇 나는 jQuery를 같은 라이브러리없이 휴대용 DOM-조작 코드를 작성하는 것은 불가능 아니라고하지만, 사람들이 거의 그렇게 없다는 것을, 비슷한 문제를 설명합니다.

프로그래밍 언어, 라이브러리 또는 프레임 워크를 사용할 때 사람들은 완벽하지만 불편하지 않은 작업을 수행하는 가장 편리하거나 관용적 인 방법을 사용하는 경향이 있습니다. 좋은 프레임 워크의 진정한 가치는 그렇지 않은 일을 쉽게하는 것입니다. 비밀은 올바른 일을 편리하게 만들어줍니다 . 결과는 여전히 가장 간단한 형태의 람다 미적분학 또는 가장 원시적 인 튜링 머신과 동일한 힘을 그대로 유지하지만 특정 개념의 상대적 표현성은 그러한 개념이 더 쉽게 또는 전혀 표현되는 경향이 있음을 의미합니다. 올바른 솔루션은 가능할뿐만 아니라 실제로 광범위하게 구현됩니다.

업데이트 5

반응 + 성능 =? 2015 년 7 월 Paul Lewis의 기사는 React가 Flickr 그림의 무한 목록을 위해 직접 작성한 바닐라 JavaScript보다 느린 경우의 예를 보여줍니다. 특히 모바일에서 중요합니다. 이 예는 모든 사람이 특정 사용 사례와 특정 대상 플랫폼 및 장치에 대해 항상 성능을 테스트해야 함을 보여줍니다.

내 관심을 끌게 해준 Kevin Lozandier 에게 감사합니다 .


75
그것이 제가 포괄적 인 답변이라고 부르는 것입니다. 감사합니다!
Demwunz

14
Atom이 React에서 멀어지는 것처럼 보입니다. github.com/atom/atom/issues/3677을 참조하십시오 .
Juho Vepsäläinen

6
@ash : 스레드를 자세히 읽으면 결국 React 및 기타 프레임 워크에서 완전히 벗어나 어떻게 사용자 정의 요소와 섀도 DOM을 사용하여 자신의 롤을 만들고 싶은지 이야기합니다.
musicfreak

3
@ErikAllik의 목록에서 위의 문구를 명확히하기 위해 FRP (Functional Reactive Programming)는 새로운 언어가 아니라 인기를 얻는 접근법입니다. 사실, (elm-lang.org에서) "느릅 나무는 기능 반응성 프로그래밍의 개념을 기반으로", 그가 언급 한 바와 같이, 등 하스켈에 대한 FRP 프레임 워크가있다
존 쿰즈

5
tl; 어쨌든 읽기-훌륭하고 자세한 답변!
Mark K Cowan

16

폴리머는 굉장합니다. 반응이 굉장합니다. 그들은 같은 것이 아닙니다.

Polymer 는 이전 버전과 호환되는 웹 구성 요소를 구축하기위한 라이브러리 입니다.

반응 은 MVC의 V입니다. 보기이며 다른 것은 없습니다. 적어도 그 자체로는 아닙니다.

반응은 프레임 워크가 아닙니다.

React + Flux + Node + (Gulp 또는 Grunt)는 프레임 워크와 더 비슷하지만 그중 3 개는 전혀 반응하지 않습니다.

개발자가 따라야하는 많은 기술, 패턴 및 아키텍처 스타일이 있지만 반응 자체는 프레임 워크가 아닙니다.

아무도 가장 간단한 것을 말하는 데 시간이 걸리지 않아서 그들이 비교해서는 안된다는 것은 슬픈 일입니다. 겹치는 부분이 있지만 같은 것보다 더 다릅니다.

둘 다 웹 구성 요소를 정의 할 수 있지만 다른 방식으로 정의 할 수 있습니다. 그것들은 매우 다른 도구입니다.


데이터 상태를 유지하고 업데이트하고 구성 요소를 통해 html 조각을 렌더링하기 때문에 V뿐만 아니라 M과 V도 반응하지 않습니까?
abelito

1
플럭스 또는 redux와 같은 반응 상태 관리 라이브러리가 있지만 react와 함께 패키지되어 있지는 않습니다.
Robotsushi

아시다시피, 우리는 View 데이터를 모델 데이터로 간주하지 않습니다. 서버 측에 제출 될 때까지. React가 컴포넌트 상태 (데이터보기)를 보유하더라도 제출할 때까지 데이터를 유지합니다. 말이 되네요
abelito

15

React 녀석은 React와 Web Components의 비교에 대해 꽤 잘 설명 했습니다.

두 가지 라이브러리가 서로 다른 문제를 해결하기 위해 구축 되었기 때문에 WebComponents와의 React와의 비교 및 ​​대조는 불가피하게 결론을 내릴 수밖에 없습니다. WebComponents는 재사용 가능한 구성 요소를 강력하게 캡슐화하고 React는 DOM을 데이터와 동기화하는 선언적 라이브러리를 제공합니다. 두 목표는 상호 보완 적입니다. 엔지니어는 기술을 혼합하여 사용할 수 있습니다. 개발자는 WebComponents에서 React를 사용하거나 React에서 WebComponents를 사용하거나 둘 다 사용할 수 있습니다.


14

한 점에서 다른 대답은 구체적으로 다음과 같습니다.

바닐라 JavaScript로 JavaScript 작성, CSS로 CSS 작성, HTML로 HTML 작성

CoffeeScript, TypeScript, ClojureScript 또는 기타 다른 언어로 Javascript를 작성하는 것을 막을 수있는 것은 없습니다. 순전히 선호의 문제입니다.

HTML은 정적 HTML 문서에 가장 적합한 DSL입니다 . 그러나 동적 HTML에는 아무것도 제공하지 않습니다. 그리고 브라우저에서 HTML을 동적으로 만드는 가장 좋은 언어는 Javascript입니다. 순수한 Javascript DOM 조작 또는 절반 언어가 아닌 Handlebar와 같은 템플릿 언어를 사용하는 순수한 HTML이 아닙니다.

CSS의 경우 CSS가 정적이면 평소대로 작성합니다. 일부 런타임 값을 기반으로 동적이어야하는 경우 HTML과 같은 이야기입니다. Javascript는 동적으로 만드는 가장 좋은 방법입니다.


1
답변을 주셔서 감사하지만 실제로는 내 요점이 아닙니다. 내 편집 내용으로 인해 질문이 좀 더 명확 해지기를 바랍니다.
CletusW

1
죄송합니다. 스타일에 관계없이 스타일을 별도의 파일로 작성할 수 있습니다. 그리고 React의 JSX는 마크 업 언어를 사용하는 것처럼 보이게합니다.
DjebbZ

3
"자바 스크립트는 [CSS]를 역동적으로 만드는 가장 좋은 방법입니다."-실제로 그 이유를 설명하지는 않습니다.
pilau

1
스타일 / 클래스가 사용자 입력 또는 비즈니스 규칙에 따라 변경되어야하는 경우 자바 스크립트를 사용하여 변경하십시오. 바닐라 js에서는 DOM 노드의 classList 또는 styles 속성을 조작합니다. React를 사용하면 Virtual DOM을 조작하는 것과 동일한 목표를 달성 할 수 있습니다. 더 명확합니까?
DjebbZ

2
React의 핵심 공헌자 인 Vjeux는 최근 React를 사용하여 "CSS in JS"개념을 추진하는 주제에 대해 이야기했습니다. 나는 그것이 재미 있다고 생각합니다, 당신은 그것이 무엇인지 기꺼이 볼 수 있습니다 : blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html
DjebbZ

6

웹 구성 요소를 사용하지 않았지만 수동으로 코딩 된 돌연변이 논리를 이벤트 처리기에 추가해야하는 것처럼 보입니다.

폴리머 예제의 스 니펫 :

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

React의 요점은 돌연변이 논리를 제거하여 복잡성을 줄이는 것입니다. 대신 가상 DOM을 순전히 재생성하고 React의 diff 알고리즘이 실제 DOM에서 변경해야 할 사항을 파악하게합니다.


5
이 예제를 어디에서 얻었는지 확실하지 않지만 Polymer는 클래스 이름을 포함하여 데이터 바인딩을 위해 수동 DOM 돌연변이를 권장하지 않습니다 .
CletusW

polymer-project.org 첫 페이지의 "요소 만들기"탭에있는 예입니다 .
limscoder

4
와우, 네 말이 맞아! 나는 그들이 자동 노드 찾기의 예를 원한다고 생각합니다. 그래도 아마도 가장 좋은 것은 아닙니다.
CletusW

6

제 생각에 React의 가장 큰 단점은 웹 표준을 기반으로하지 않는다는 것입니다. React는 현재 매우 강력한 도구이지만 가능한 경우 브라우저가 제공하는 많은 기능을 우회하기 때문에 브라우저의 내장 기능이 계속 유지되면서 몇 년 후에는 의미가있는 결정이 의미가 없을 것입니다. 돌리다. 이에 대해 이야기하고 그것이 웹 응용 프로그램의 몇 가지 다른 측면에 미치는 영향에 대해 이야기하고 싶습니다.

공연

사람들은 React의 장점이 전체 DOM 및 이벤트 모델을 완전히 재발 명하고 기존 표준 DOM이 무겁고 비싸고 그렇지 않다는 주장을 좋아합니다.하지만 하루가 끝나면 성능을 찾지 못했습니다. 잘 작성된 Backbone 또는 Polymer 응용 프로그램에서 얻을 수있는 것보다 낫습니다. 사실, 대부분의 전문적인 경험에서 React의 성능은 실제로 약간 나빴습니다. 그것은 React가 느리다는 것을 말하는 것이 아닙니다 ... 그것은 우리가 손을 잡기 전에 생각했던 최첨단 성능 선택이 아닙니다.

rsp의 답변에서 그는 div에 대한 React의 DOM 모델 이 네이티브 DOM div보다 훨씬 가볍고 확실히 사실이라고 지적합니다. 그러나 React가 유용하기 위해서는 '가상'div가 어느 시점에서 실제 div가되어야합니다. 내 세계보기에서 그것은 React div 대 native div의 문제가 아닙니다. 그것은 React div + native div 대 native div입니다. React의 DOM 버전 오버 헤드는 사소한 것이 아니며, 표준이 불필요한 속성 중 일부를 삭제하고 네이티브 DOM 노드가 훨씬 가벼워지면 갑자기 오버 헤드가 실제로 비싸 질 것입니다.

필자의 이전 직장 중 하나에서 Polymer에 일부 응용 프로그램을, React에 일부 응용 프로그램을 사용했습니다. 초기 Polymer 응용 프로그램 중 하나는 React에서 다시 작성되었습니다. 왜냐하면 회사가 표준으로 삼 았던 것이기 때문입니다. 그리고 동일한 응용 프로그램의 React 버전을 사용하여 측정 한 결과, Polymer 버전보다 약 30 % 더 많은 메모리를 사용했습니다. 차이는 미미했지만 폴리머 버전도 더 짧은 시간 안에 렌더링되었습니다. 여기서 고려해야 할 것은 사람들이 작성한 응용 프로그램에 대해 이야기하고 사람들이 완벽하지 않다는 것입니다. 따라서이 응용 프로그램의 React 구현이 React가 할 수있는 모든 것을 활용하지 않았을 수 있습니다. 그러나 적어도 일부는 React가 DOM의 자체 버전을 갖는 데 따른 오버 헤드와 관련이 있다고 생각합니다.

React는 자체 모델을 사용하여 전체 DOM을 다시 발명 한 다음 주요 성능 최적화에 사용합니다. 뷰는 가상 DOM으로 렌더링되고 실제 DOM으로 투영됩니다. 변경 사항이 있고 뷰를 업데이트해야 할 때 뷰가 다시 가상 DOM으로 다시 렌더링되고이 트리는 이전 트리와 비교하여이 변경 사항을 반영하기 위해 실제 DOM에서 어떤 노드를 변경해야하는지 결정합니다. 보기에서. 이는 효율적인 DOM 업데이트를위한 매우 현명한 접근 방법이지만 이러한 모든 가상 DOM 트리를 유지 관리하고 실제 DOM에서 변경해야 할 사항을 결정하는 데는 어려움이 있습니다. 현재이 오버 헤드는 성능상의 이점으로 인해 크게 상쇄되지만 시간이 지남에 따라 기본 DOM이 개선됨에 따라 스케일이 다른 방향으로 이동합니다. React 앱의 수명에 대해 걱정합니다. 3 년 안에 DOM을보다 직접적으로 다루는 것보다 훨씬 느릴 것입니다. 이 가상 DOM 접근 방식은 약간의 썰매 망치이며 Polymer와 같은 다른 라이브러리는 DOM을 훨씬 더 미묘한 방식으로 처리하기 위해 매우 효율적인 접근 방식을 구현할 수있었습니다.

성능 업데이트 : 얼마 전에 우연히 발견 된 라이브러리 중 하나가 DOM 업데이트를 관리하는 더 나은 작업이라고 생각합니다. Google의 Incremental Dom 라이브러리이며 dom과 함께 작동하며 '가상 복사본'을 만들 필요가 없다는 사실은 훨씬 적은 메모리 오버 헤드로 훨씬 깨끗한 접근 방식이라고 생각합니다. 자세한 내용은 여기를 참조하십시오 : http://google.github.io/incremental-dom/#about

선언적 구성 요소와 명령형 구성 요소

응용 프로그램을 구성 요소 화하는 것에 대해 이야기 할 때 항상 듣게되는 것 중 하나는 구성 요소가 선언적이라는 이점입니다. React의 세계관 안에서 모든 것이 훌륭하고 선언적입니다. 마크 업을 반환하는 자바 스크립트를 작성하고 리 액트가이를 결합합니다. React 만 사용하고 전혀 다른 새로운 응용 프로그램을 다루는 경우 좋습니다. 일부 컴포넌트를 작성할 수 있으며 React 소유 DOM 부분 안에있는 한 컴포넌트를 사용하기 위해 해당 태그를 페이지에 배치하는 것만 큼 간단합니다.

그러나 이러한 구성 요소를 가져 와서 React 외부에서 사용하자마자 상황이 더 복잡해집니다. React 컴포넌트가 태그로 만들어지는 방식은 웹 표준이 제공하는 것과 완전히 다르기 때문에 React 외에는 이러한 컴포넌트를 소비하는 선언적 방법을 제공하는 방법을 모릅니다. Handlebars 템플릿을 사용하는 기존 백본 뷰에 React 구성 요소를 배치하려면 핸들로 사용할 수있는 클래스 또는 ID로 템플릿에서 더미 div를 렌더링 한 다음 더미 JavaScript를 작성하여 해당 더미 div 및 마운트를 찾아야합니다. 당신의 구성 요소. 서버 측 템플릿을 사용하는 Express.js 응용 프로그램이 있습니까? 같은 노래와 춤입니다. JSP 페이지? 당신은 웃고 있지만 여전히 많은 응용 프로그램을 사용하고 있습니다. 기존 코드없이 시작하는 것이 아니라면 여러 애플리케이션에서 React 구성 요소를 재사용하려면 배관을 작성해야합니다. 한편, Polymer는 웹 구성 요소 표준을 통해 구성 요소를 달성하고 사용자 지정 요소 사양을 사용하여 브라우저가 기본적으로 소비하는 방법을 알고있는 구성 요소를 작성할 수 있습니다. Polymer 구성 요소를 JSP 페이지, Express.js 템플릿, ASP.NET 뷰, 백본 뷰 등에도 넣을 수 있습니다. 말 그대로 HTML을 사용할 수있는 곳이라면 어디서나 Polymer 구성 요소를 사용할 수 있습니다. 재사용을 위해 엔지니어링하는 사람들은 웹 표준을 찾고 있습니다. 표준은 서로 호환이 잘되는 계약이기 때문입니다. YouTube는 Polymer에서 점점 더 많은 자료를 제작하고 있습니다 (출처 : Polymer는 웹 구성 요소 표준을 통해 구성 요소를 달성하고 사용자 지정 요소 사양을 사용하여 브라우저가 기본적으로 소비 방법을 알고있는 구성 요소를 작성할 수 있습니다. Polymer 구성 요소를 JSP 페이지, Express.js 템플릿, ASP.NET 뷰, 백본 뷰 등에도 넣을 수 있습니다. 말 그대로 HTML을 사용할 수있는 곳이라면 어디서나 Polymer 구성 요소를 사용할 수 있습니다. 재사용을 위해 엔지니어링하는 사람들은 웹 표준을 찾고 있습니다. 표준은 서로 호환이 잘되는 계약이기 때문입니다. YouTube는 Polymer에서 점점 더 많은 자료를 제작하고 있습니다 (출처 : Polymer는 웹 구성 요소 표준을 통해 구성 요소를 달성하고 사용자 지정 요소 사양을 사용하여 브라우저가 기본적으로 소비 방법을 알고있는 구성 요소를 작성할 수 있습니다. Polymer 구성 요소를 JSP 페이지, Express.js 템플릿, ASP.NET 뷰, 백본 뷰 등에도 넣을 수 있습니다. 말 그대로 HTML을 사용할 수있는 곳이라면 어디서나 Polymer 구성 요소를 사용할 수 있습니다. 재사용을 위해 엔지니어링하는 사람들은 웹 표준을 찾고 있습니다. 표준은 서로 호환이 잘되는 계약이기 때문입니다. YouTube는 Polymer에서 점점 더 많은 자료를 제작하고 있습니다 (출처 : Polymer 구성 요소를 JSP 페이지, Express.js 템플릿, ASP.NET 뷰, 백본 뷰 등에도 넣을 수 있습니다. 말 그대로 HTML을 사용할 수있는 곳이라면 어디서나 Polymer 구성 요소를 사용할 수 있습니다. 재사용을 위해 엔지니어링하는 사람들은 웹 표준을 찾고 있습니다. 표준은 서로 호환이 잘되는 계약이기 때문입니다. YouTube는 Polymer에서 점점 더 많은 자료를 제작하고 있습니다 (출처 : Polymer 구성 요소를 JSP 페이지, Express.js 템플릿, ASP.NET 뷰, 백본 뷰 등에도 넣을 수 있습니다. 말 그대로 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는 브라우저에서 브라우저를 켜고 구축하는 대신 모든 구성 요소를 동기화하는 복잡한 메커니즘 대신 웹 구성 요소 표준 중 일부를 사용하여 수행하는 경우 훨씬 나아질 것이라고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.