From ReactJS wiki page about Virtual DOM:
React creates an in-memory data structure cache, computes the
resulting differences, and then updates the browser's displayed DOM
efficiently. This allows the programmer to write code as if the
entire page is rendered on each change while the React libraries only
render subcomponents that actually change.
In other words, Virtual DOM allows us to improve performance by avoiding direct manipulations with DOM.
But what about React Native?
We know that in theory on other platforms there are native views and UI components. There is nothing about DOM itself. So can we say React Native has "Virtual DOM" there or we're talking about something else?
For example, there is a section in Weex specs which describes methods to work with DOM-tree directly. And my assumption is that potentially we can think React Native should have some sort of DOM-tree too as well as "Virtual DOM" abstraction layer which is the main idea of React itself.
So my question is:
Does React Native have some sort of "Virtual DOM" (or its representation) and if so, how this "Virtual DOM" is ported to various platforms?
UPDATE:
The goal of this question is to shed some light on how React Native manage rendering of native UI components. Is there any specific approach and if so, how it's officially called?
UPDATE 2:
This article describes new React architecture called Fiber which looks like the answer on this question.
In Short
Well.. in essence, yes, just like Reactjs's Virtual DOM, React-Native creates a tree hierarchy to define the initial layout and creates a diff of that tree on each layout change to optimize the renderings. Except React-Native manages the UI updates through couple of architecture layers that in the end translate how views should be rendered while trying to optimize the changes to a minimum in order to deliver the fastest rendering possible.
A more detailed explanation
In order to understand how react native creates views in the background, you'll need to understand the fundamentals, and for that, I'd rather start from the ground up
1.The Yoga layout engine
Yoga is a cross-platform layout engine written in C which implements Flexbox through bindings to the native views (Java Android Views / Objective-C iOS UIKit).
All the layout calculations of the various views, texts and images in React-Native are done through yoga, this is basically the last step before our views get displayed on the screen
2. Shadow tree/Shadow nodes
When react-native sends the commands to render the layout, a group of shadow nodes are assembled to build shadow tree which represented the mutable native side of the layout (i.e: written in the corresponding native respective language, Java for Android and Objective-C for iOS) which is then translated to the actual views on screen (using Yoga).
3. ViewManager
The ViewManger is an interface that knows how to translate the View Types sent from the JavaScript into their native UI components.
The ViewManager knows how to create a shadow node, a native view node and to update the views.
In the React-Native framework, there are a lot of ViewManager that enable the usage of the native components.
If for example, you'd someday like to create a new custom view and add it to react-native, that view will have to implement the ViewManager interface
4. UIManager
The UIManager is the final piece of the puzzle, or actually the first.
The JavaScript JSX declarative commands are sent to the native as Imperative commands that tell React-Native how to layout the views, step by step iteratively.
So as a first render, the UIManager will dispatch the command to create the necessary views and will continue to send the update diffs as the UI of the app changes over time.
So React-Native basically still uses Reactjs's ability to calculate The difference between the previous and the current rendering representation and dispatches the events to the UIManager accordingly
To know about the process a bit more in depth, I recommend the following presentation by Emil Sjölander from the React-Native EU 2017 Conference in Wroclaw
I don't know if this is the answer to your question but I found this in the the official React docs:
React builds and maintains an internal representation of the rendered UI. It includes the React elements you return from your components. This representation lets React avoid creating DOM nodes and accessing existing ones beyond necessity, as that can be slower than operations on JavaScript objects. Sometimes it is referred to as a "virtual DOM", but it works the same way on React Native.
So I would say that yes, it manages a very similar internal representation to the one used in React.js. Then I guess that it uses Javascript APIs to render native views just like the article you read suggests.
EDIT
This post provided by Sebas in a comment is also interesting because a member of the React (and React Native) team says that:
React Native shows that ReactJS has always been more about "zero DOM" than "virtual DOM" (contrary to popular belief).
It seems like the so-called 'React virtual DOM' is much closer to an internal structure/representation of the elements that can be mapped to various technologies than to a HTML DOM.
This article describes new React architecture called Fiber. It seems to be the correct answer about what's going on in React Native or at least what React Native will be trying to achieve in the nearest future.
The DOM is just one of the rendering environments React can render to,
the other major targets being native iOS and Android views via React
Native. (This is why "virtual DOM" is a bit of a misnomer.)
The reason it can support so many targets is because React is designed
so that reconciliation and rendering are separate phases. The
reconciler does the work of computing which parts of a tree have
changed; the renderer then uses that information to actually update
the rendered app.
This separation means that React DOM and React Native can use their
own renderers while sharing the same reconciler, provided by React
core.
Fiber reimplements the reconciler.
Here's an over-simplification: ReactJS outputs the DOM that can be rendered the browsers. As you already know, the virtual DOM helps ReactJS efficiently keeps track of the delta of what has changed. For React Native for iOS, ultimately it outputs UIKit code. Same thing with React Native for Android, but instead of outputting DOM or UI Kit, the output is created using Android SDKs. So virtual DOM is just an intermediate step. It can be considered as a combination of the internal data structure to hold the data that describes where to render the button and textbox, what happens when you tab the button, etc, and an efficient algorithm to keep track what has changed. The same code can be used for all platforms. Only the final step is different. Depending on the platform, it has code that generates the DOM, UIKit code, or whatever name Android UI lib is called.
Related
I'm currently learning Front-end web development and the difference between Vanilla JavaScript, frameworks and libraries (React for example).
Now I'm familiar with web components for making new custom HTML tags. As I know, React is made for the same purpose, but when I visited the Instagram website (the first website that uses React that comes to mind) and looked at the HTML code, I didn't find any custom HTML element, in fact, most of the elements are made of "div"s tags.
If a complex social media website like Instagram isn't made of custom elements, then who uses them and why?
React is a totally different beast, dating back almost a decade. It was developed by Facebook because TOO many teams were doing TOO many updates in the same DOM. So they came up with a virtual DOM where all required DOM updates are merged before writing to the Browser DOM.
Works great for Facebook. Newer technologies like the Custom Elements API and Svelte (Compile, don't Transpile) have proven it is no longer the best solution.
Reacts outdated technology now scores a meager 71% on https://custom-elements-everywhere.com/
React and W3C Custom Elements are not friends
Because the Green DOM elements are not tracked by React.
And if you want to mix Green and Yellow you have to basically re-write/wrap each and every component into React syntax. Because React not only does DOM Elements different, but also does DOM Events different.
The future
This makes an interesting future: React and the W3C standard are diverging.
And the W3C standard is defacto set by Browser vendors,
not by the W3C, as we learned from the never implemented ECMAScript 4 saga (1999 - 2008)
So its
Apple (Safari) + Mozilla (FireFox) + Google/Microsoft (Chromium/Chredge)
versus
Facebook (No browser!)
'problem' with the W3C is all members have to agree on a standard; that is why it took years for the Custom Elements API to mature... and React got a head start
Facebook does now "own" 60% of the developers market...
but hey,
Microsoft had 90% of the Browser market... once,
and Flash was installed on nearly every device....once
The Custom Elements API will exist for as long as ECMAScript runs in the browser
It is not a framework or library! It is a language construct.
Not learning Custom Elements is like saying:
I am not learning Set or Map, I can do everything with Arrays
Older rant at: Web components - Services / non html components
Or believe the 2020 Front-End Survey:
As you said, instagram uses react which doesn't transpile to web components
react is not the only components based lib to NOT use web components, there's also ¹ : vue.js, Polymer.
But some other components based lib do use web components as their base ¹ : slim.js, stencil.
All of these libs can be used with webcomponents, some even tell us how to do: react, vuejs.
!!! this part may be considered as opinion based !!!
AFAIK the lib which chose not to use webcomponents were created before the web components API was finalized, and the cost to rewrite using them is too big.
!!! this part is opinion based !!!
Most person uses lib because web components doesn't give the same effortless two way binding.
In opposition webcomponents seem to give more control about when the component reload and how the binding is done, but it needs to be coded which is extra work.
¹ based on the list of custom elements returned by this script on the main page of each lib
In React it's different.
Working with React you are using JSX.
This is just tag syntax, which is neither a string nor HTML.
Under the hood this syntax in converting to usual JavaScript(using Babel).
You can read more about it here.
I want to know what is main problem between javascript and DOM that Angular / React / Vue try to solve,
Please guide me I'm new learning Angular.
React and Vue use a pattern called the Virtual DOM to optimize updating the DOM in order to render changes faster. Angular uses another method with similar motivations. Web technologies weren't originally designed to build robust applications in the browser. These frameworks attempt to enhance application performance and improve the developer and end-user experience until web standards catch up to modern use cases.
The virtual DOM (VDOM) is a programming concept where an ideal, or “virtual”, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM. This process is called reconciliation.
Source: https://reactjs.org/docs/faq-internals.html
Your question is one of the difference between SPA (Single Page Applications) vs MPA (Multi-page Applications).
All of Vue, React and Angular use an SPA design to only update DOM elements that are changed, instead of reloading the entire page. This is the main problem that these frameworks aim to solve instead of using vanilla javascript.
The short answer to your question would be: because accessing the DOM elements is "expensive" (in terms of browser resources, memory, speed). That's why we have a Virtual DOM, a temporary copy of DOM which is purely in JS, and accessing, adding, modifying, and deleting elements is significantly faster, and that's why applications written in Angular, React or Vue has better performance.
Is Web Components give better performance when compared to Native HTML elements. Since each elements getting mutated only when getting attached to DOM. So, expensive operations inside Element callbacks leads to poor performance.
I wrote one sample Web Component with some expensive implementation in connectedCallback handle, When I try render the component, each component took time in a consecutive order.
I don't see any reference related performance pin points on Web Components.
Update 1
I have a created small page with Native and Web Component implementation, Seems Web Components page took 4ms to finish but Native took only 1ms. Refer my Performance screens. In Web Components scripting is taking more time.
Native HTML Example:
Web Component Example:
Since Custom Elements are extending native HTML elements (through class extends HTMLDivElement), with extra features added, I would say: in the best case, they can only be as good as native HTML elements.
The gain in performance is when compared with 3rd party frameworks (that don't leverage this new technology): Web Components should be faster.
You can see it when comparing native vs polyfilled Custom Elements implementations.
You can greatly improve the performances of your web component using StencilJS (github). It will do a lot of optimisation work pretty easily, as well as implementing a Virtual DOM to your web component for an optimal rendering.
You can check the performances here.
I am thinking if you just plainly do a simple "Hello World", of course Native Elements will be the winner because it doesn't need JS to work while Custom Elements will need JS to define and startup the rendering of the text.
Now, a better comparison is when, let's say, using the same code base, you create a carousel using JS and Native elements only, and a custom element that is a carousel. Then I think rendering performance would be equal. The only advantage I can think of on using custom elements rather than manipulating a native element via JS is that you can reuse the custom tag anywhere and it will work as a carousel, rather than when you have to use new Carousel(document.querySelector('.carousel')) on every carousel div that you created using only native elements.
Native HTML Elements will always be the winner, since Web Components are implementing them, which adds an extra layer of "complexity".
I personally don't think Web Components are introduced to outperform Native HTML Elements (you can say the same for Js Frameworks like Angular, React & Vue). I think they're made for convenience and to make the life of developers much easier. Since we're writing code for humans and in the second place computers, an important aspect of web development is readability, which improves enormously with Web Components.
IMHO a better comparison between Native HTML Elements and Web Components will be the extent to which it supports developers to write more readable code and be more productive.
I have a performance issues with Angular (as many others). I wish to change only the view layer to either reactjs or Mithril. I found examples of React js (for example http://www.bimeanalytics.com/engineering-blog/you-put-your-react-into-my-angular/), but not of Mithril.
Can anyone advice to the pros and cons of using Mithril as an angular view vs Reactjs?
Thank you!
I don't think there's an objective answer here, and as a Mithril user I have my biases, but here is what I think.
In terms of philosophy, Mithril and React are quite similar: you write view functions that describe how your app should look at any given time. In terms of rendering performance, I don't think there's a clear winner. There are links / blog posts that say Mithril is faster than React, and vice versa.
So instead what I think you should focus on is:
1) Which API do you prefer? With React you should use JSX lest you have to reverse engineer their documentation. Mithril also just has one lifecycle hook (the view function), whereas React has several (such as shouldComponentUpdate) -- do you need all those hooks?
2) Community support -- React is the clear winner here, and the fact that there are existing examples of integration with Angular is a win.
3) Compatibility - DOM redrawing / diffing in React is done when data changes, just like Angular, but Mithril's redraw is centered around user interaction (such as clicks, route changes, ajax requests). You can manually redraw, but that's less desirable. I don't know how well Mithril will fit into an Angular setup.
Should you decide to use Mithril, I'd encourage you to use the Google group (https://groups.google.com/forum/#!forum/mithriljs) as a resource, or at least report back on your experience.
Mithril and React have many similarities. I've used both of them and here are some pros and cons.
Mithril
Pros: It's loading times are very fast. This is because it's templates are compiled first and then served to the browser. You can write Mithril views in JavaScript. Small size, good documentation and doesn't force you into a predefined structure.
Cons: Small API can make it unsuitable for larger more complex projects.
ReactJS
Pros: React's one-way data binding means that it's easy to see where and how your UI is updated and where you need to make changes. It also provides server-side rendering, virtual dom support, good debugging tools, easy to write tests, easy to reuse components, flux architecture patterns, and extensive SVG supports etc.
Cons: Heavy on memory compared to Mithril, not a complete solution as it mainly focuses on the view, and need to learn a new syntax etc.
In my view, React is overall preferable. But, if your application doesn't need all these extra stuff that React provides, you should go with Mithril.
I'm very new to the React and Flux consept and I'm confused as hell..
I come from a background of Sails.js so I can't really tell whats what with React.
I plan to use Sails.js (as a restful api, isolated from the front end)
+
React (as my front end using restful calls + perhaps websockets to communicate with sails)
but I don't see where flux fits in!
No.
Flux is a design pattern, rather than a framework or library. You can use Flux without using React and vice versa, although they are optimized to work well with each other.
Flux applications have three major parts: the Dispatcher, the Stores, and the Views (not be confused with Model-View-Controller). EventEmitter is typically used as a basis for Stores and React as a basis for Views. The one piece of Flux not readily available elsewhere is the Dispatcher, although you could write one yourself if you want.
Controllers do exist in a Flux application, but they are controller-views -- Views often found at the top of the hierarchy that retrieve data from the stores and pass this data down to their children. Additionally, action creators — dispatcher helper methods — are often used to support a semantic dispatcher API.
Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with a React view, the view propagates an Action through a central Dispatcher, to the various Stores that hold the application's data and business logic, which updates all of the views that are affected. While you don't need React to implement this pattern per se, it is designed to work especially well with React's declarative programming style, which allows the store to send updates without specifying how to transition views between states.
More info can be found at the official Flux repo.
Flux is definitely not a requirement for using React and does not operate as a "back-end" for React. It's just a common pattern for structuring applications written with React. It's well documented here.
It is only a client side solution. It does not have a hard requirement on any particular web server (but it is convenient if you have NodeJS installed so that you can use something like Browserify to compile and package scripts).
It's not clear from your question what parts of Sails you're planning to use. If you want to use React in an isomorphic way (meaning you'd run React code on the web server and it would be then "attached" by the React client code, without re-rendering), then data management could be an issue if you're using Waterline. But, if you're only going to use React on the client, then it may be an easier integration.
But, again, it's not necessary to use Flux. You can just follow the basic principles of using React JS regarding data flow (parent to child) and use other data storage and synchronization libraries. React is not opinionated that way.
Also, while Facebook has a Flux implementation here, you'll find dozens of implementations of the pattern with various tweaks and enhancements located here. You'll also note on that same page that there are lots of other complimentary libraries that may be useful.