facebook / react

The library for web and native user interfaces.

Home Page:https://react.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

React and WebComponents

cosminnicula opened this issue · comments

I see a lot of questions, blog posts and discussions around React and WebComponents, but none of them are actually an official statement from Facebook that could clarify whether or not React will going to implement WebComponents W3C specs in the future.

There are also quite a few GitHub Issues around this subject, like "Enable rendering into shadow roots" #1167, "Allow rendering into a document fragment" #840, "Track upcoming DOM technology upgrades" #2836, "Proof of concept: Shadow DOM support" #1877, "Support for custom DOM elements & attributes" #2746, "Templates?" #2286, "Add naive custom element support" #1249, "Add support in the future for custom elements" #1214 etc.

Nevertheless there are some open-source projects that allows React to be WebComponents-aware, like https://github.com/Wildhoney/Maple.js, https://github.com/wix/react-templates or https://github.com/PixelsCommander/ReactiveElements

As for WebComponents, it seems that the reconciliation between HTML Imports and ES6 Modules is inevitable, thus the HTML Imports part of the spec might need to change in order to be widely accepted among the open-source community and browser vendors https://bugzilla.mozilla.org/show_bug.cgi?id=877072 Until then, wrapping components and importing them as ES6 Modules is as good as including them in HTML pages and importing them with <link rel="import" />

The Custom Elements are more or less about defining new markup that you can interact in the same way as with native HTML elements, allowing you to extend existing native HTML elements and giving you some lifecycle methods. This is already possible with React and JSX, even though JSX's XHTML-like syntax transpiles to JavaScript which ultimately becomes HTML through the Virtual DOM.

Shadow DOM is hard and in some cases even impossible to be polyfilled. This is the reason why Polymer is using Shady DOM https://www.polymer-project.org/1.0/articles/shadydom.html With the current browser support http://caniuse.com/#feat=shadowdom, adopting BEM conventions or even inline styles backed by JavaScript objects, which is what React is doing, remains a viable alternative but still is different from Shadow DOM.

Templates are really pointless without data binding. Two-way data binding is slow because the Object.observe polyfill (https://github.com/Polymer/observe-js) is slow. Also, two-way data binding is about code complexity and the fact that the more dependencies you have between between components, the bigger the complexity grows, as opposed to unidirectional data flow. React's one-way data flow with immutable data structures has the potential to scale and be highly performant, especially if we think about large-scale applications and complex interactions between thousands of entities.

Even though the open-source community is looking both at React and WebComponents, in the end the developer experience is what matters most and drives adoption. No doubt standards are having their own place in this.

Therefore, my question is: what is React's strategy for WebComponents?

@sebmarkbage any thoughts?

The primary component strategy for React will never be Web Components. It runs counter to functional paradigm of React by providing a mostly imperative API. It doesn't help solve any of the problems we have building apps. In fact it makes it more difficult. It does little to nothing to solve the integration problem with other libraries. It doesn't have a solid story around server-side rendering. It doesn't help at all for cross-platform environments like React Native because the overhead of implementing a full DOM spec that we're then going to have to side-step anyway.

It is unlikely that Facebook will ever use Web Components at scale and therefore unlikely it will be a priority for us. There has been a lot of excitement about Web Components as an interop layer. Mostly unwarranted IMO.

However, we like to support our users so we've made a best effort to try to support interop in the edges. We would like to support as much as possible without compromising the API and vision of React itself.

It has turned out that the spec is incomplete with regard to things like event delegation and there are still major changes being pushed from various sides, such as Mozilla. What was in Polymer/Chrome is not the final incarnation so we've had to revert some of the support that we already added (e.g. support for event handling in shadow trees).

In terms of strategy, we'll go forward with as if it didn't exist and try to improve interop at the React or React-like component layer instead. I've talked with members of other popular UI frameworks and they seem to feel the same. In fact, we probably have a better chance at implementing solid interop in user land.

Just to recap, there are two types of approaches in terms of how the UI frameworks allows you to build components:

  • using the DOM as a framework and leveraging DOM's component model through Custom Elements and its declarative format - e.g. Polymer
  • using a proprietary, non-standard, component model and nevermind about extending the DOM, since we only care about our code to be re-usable, encapsulated, highly performant and interoperable just like native HTML elements - e.g. React

So basically the ones that are relying on the first approach will have to build their frameworks on top of incomplete specs and potentially dangerous ground.
Also I'm wondering if there will ever be a real performance advantage in terms of browser optimizations for the first approach over React.

Coming back to the interop subject, I have a question: what do you think about wrapping React components as Custom Elements (https://github.com/PixelsCommander/ReactiveElements) rather than exposing a different wrapper for each particular UI framework? I'm asking this in the context of supporting older technologies that want to benefit from React.

And lastly, can you share some insights on what WebComponents' "imperative API" refers to? I guess is not related to HTML's declarative format or to the traditional declarative data-binding expressions.

commented

@cosminnicula The key difference is that custom elements (web components) often expose an imperative API. As an example, consider a video tag/element. There are some relatively declarative attributes (like src) but there are also a bunch of imperative functions (eg. addTextTrack(), canPlayType(), load(), play(), pause()). These functions do not play nicely in a declarative application.

We touched on this a bit in our most recent blog post: http://facebook.github.io/react/blog/2015/10/01/react-render-and-top-level-api.html#object-oriented-updates

We try to support interoperability where possible/practical. For web components that support a purely declarative API via HTML attributes, they should already work reasonably well with React.

With regards to wrapping React components as custom elements (or vice versa)... Yes, wrapping is the current recommendation for anyone who requires such interoperability. Since the programming models are different, it's hard to have a seamless API that is automatically generated, so our recommendation is that you write the wrapper class by hand (rather than using an automatic wrapper library), but ultimately it's your choice and you should do whatever works for you. It should be possible to wrap any custom element in a React-wrapper for use in a React application, and vice versa.

@cosminnicula why do you consider an open source project, adopted by many big companies (some competitors to Facebook) to be 'proprietary, non-standard'.

The adoption of the two technologies, might hint at which one of them solves the real world problems better.

@borisyankov simply because React's one-way data flow and component model will never converge towards W3C WebComponents standard. The reconciliation between these two is possible only at the interoperability level. The only way that React's ideology could be considered "standard" is to actually be supported by W3C.

I really think that React is solving two important problems which ultimately drives adoption: DOM performance and code complexity. However, WebComponents and Custom Elements might just get a substantial performance boost with Google's Accelerated Mobile Pages.

@cosminnicula That's a misconception. WebComponents in Accelerated Mobile Pages is the SLOW path. It is deferred until the last possible point. It is intentionally the opposite of giving them a performance boost. It is to make everything else isolated.

At best it could be the interop layer where you start your component, however, once you're inside the Web Component it is still as slow as the DOM and React will be faster inside of it. It doesn't mean React should render Web Components as its output. Potentially only placeholders for server-side rendering into a AMP document.

commented

+1

mark

@majorye if your intent was to get notifications there's a subscribe button in the top right of each issue.

commented

We have merged some docs on using Web Components within React: http://facebook.github.io/react/docs/webcomponents.html

Those docs, combined with our posts in this issue, is roughly all we have to say on this topic at the moment. Unless there are further questions, I think we can close out this issue.

Related, we have a wrapper that can convert a web component into a React component: https://github.com/webcomponents/react-integration so you can use a web component as a first-class citizen within React components.

"React and Web Components are built to solve different problems. Web Components provide strong encapsulation for reusable components, while React provides a declarative library that keeps the DOM in sync with your data. The two goals are complementary. As a developer, you are free to use React in your Web Components, or to use Web Components in React, or both."

https://facebook.github.io/react/docs/web-components.html

skatejs has an interesting opinion on this enclosed in their docs.

Skate is written on top of W3C standards. The React authors have been very vocal about this. However, the response to that issue is incorrect. Web Components by nature are declarative: it's just HTML. Web Components also completely solve the integration problems between libraries and frameworks due to the nature of how Custom Elements and Shadow DOM work: Custom Elements provide a declarative API, Shadow DOM hides the implementation details. When integrating with frameworks, you're just writing HTML. In terms of the problems with imperative APIs, it's not the fault of Web Components that force a user to call a method, it's the fault of the design of the Web Component. There's nothing stopping a Web Component from being completely declarative, especially if it's written in Skate. More information about web component design.

It would be interesting to see the React teams opinion on this.

The way you've worded it, It feels like you're trying to stir up the pot.
Be it as it may, it may be worth revising as it's quite old. I'd be
interested in iterating on it if anyone has any input. It's not worth
arguing over.

On Fri., 4 Nov. 2016, 21:33 Adam Thomas, notifications@github.com wrote:

skatejs https://github.com/skatejs/skatejs has an interesting opinion
on this enclosed in their docs.

Skate is written on top of W3C standards. The React authors have been very
vocal about this. However, the response to that issue is incorrect. Web
Components by nature are declarative: it's just HTML. Web Components also
completely solve the integration problems between libraries and frameworks
due to the nature of how Custom Elements and Shadow DOM work: Custom
Elements provide a declarative API, Shadow DOM hides the implementation
details. When integrating with frameworks, you're just writing HTML. In
terms of the problems with imperative APIs, it's not the fault of Web
Components that force a user to call a method, it's the fault of the design
of the Web Component. There's nothing stopping a Web Component from being
completely declarative, especially if it's written in Skate. More
information about web component design.

It would be interesting to see the React teams opinion on this.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#5052 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIVbGpqHk73dO3vZF4ah4AlNoejIG9Bks5q6woTgaJpZM4GI861
.

Not at all, sorry it came across that way. I myself have no opinion on this and the crowd wisdom doesn't seem to be pointing either way. Its not argument, its debate.

No worries and I'm overly defensive about when it comes to the two
communities. I've seen - and unfortunately participated in - several
divisive and subjective conversations both privately and publicly, and it's
never resulted in a positive outcome other than when both parties have
dropped bias and worked toward a common goal.

I'm very interested to discuss etc.

On Sat., 5 Nov. 2016, 00:51 Adam Thomas, notifications@github.com wrote:

Not at all, sorry it came across that way. I myself have no opinion on
this and the crowd wisdom doesn't seem to be pointing either way. Its not
argument, its debate.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#5052 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAIVbEDz4FGvL-srg7Zy3KnMLwQbAdnBks5q6zhMgaJpZM4GI861
.