The ReactJS website states that,
When the data changes, React conceptually hits the "refresh" button, and knows to only update the changed parts.
What does this mean exactly?
How is this achieved?
How is this different from what AngularJS does?
Reactjs create a virtual DOM and does not touch to the real DOM. Then when some of DOM changed, it will use diff algorithm to find out what is different from previous state of DOM elements, finally just replace that changes. You can see this link for that algorithm to have more understanding. And you have to know what is shadow DOM as well.
Here's a great resource explaining why ReactJS was developed and how it differs from other frameworks like AngularJS:
http://www.quora.com/Pete-Hunt/Posts/Facebooks-React-vs-AngularJS-A-Closer-Look
"A lot of the heavyweight contenders for MVVM frameworks have a hard time rendering large amounts of data, like in lists and such. React doesn’t have that problem, as it renders only what’s changed.
For example, if a user is viewing a list of 100 items rendered with React, and he or she changes the third one down somehow, only that item gets rerendered, leaving the other 99 items unchanged."
(https://www.codementor.io/reactjs/tutorial/react-vs-angularjs)
Related
I'm creating an app using Nodejs and Vuejs 3. In this app I have made a sidebar that gets all links from a routes file and present them. This sidebar consists in a component that parents a list of other recursive link components.
Since the links are recursive and many, I find it hard to deal with class toggling (active, showing, collapsed, etc.) on each of them and relate them to one another (if one is active the others shouldn't be) using only Vue. Should I use querySelector or any frameworks such as JQuery to handle them or should I try to stick with a pure Vuejs approach?
Edit:
I don't want to gather the community's opinion on it. My aim is to understand pragmatically why I should or shouldn't manipulate the DOM "outside" of Vue.
If you're using Vue then let it be in control of the DOM; mucking around directly will only create conflicts and woe.
(The same applies to other SPA frameworks such as React and Angular.)
The main reason not to touch the DOM is that Vue works by modifying the DOM on its own, and expects to have complete control over it: when rendering components the framework is removing old DOM elements, adding new ones, updating event bindings, etc; and a lot of it is optimized to only update the DOM nodes that need to be updated.
If you go in there and start making direct changes that Vue doesn't know about, then it's likely that your own changes will get overwritten by Vue the next time it needs to render, or that your changes will overwrite bindings that Vue is depending on.
If you're very knowledgeable about Vue's lifecycle and know how to control when it does and does not render, it is possible to work with both together -- but even then it's still not a great idea. Vue and jQuery do very similar things, but in utterly different ways. In jQuery you build up the page and then use DOM traversals and event handlers to modify it; everything lives inside the DOM. In Vue you build up a bunch of components that manage their own state and rendering; the DOM is basically a side effect of the application state.
By trying to use both together you lose most of the advantages of each of them in isolation, and introduce a lot of complexity in having to manage two competing theories of state and render management (not to mention dealing with communicating data between them). Every time I've contemplated embedding a jQuery widget inside a Vue app, it's turned out to be much easier to just rewrite the widget in Vue directly.
This does mean changing a lot of habits about working with the DOM that you may have built up from past jQuery work. It sounds like you're trying to draw the whole DOM and then build your control structure into it afterwards, which is a natural way to think if you're used to jQuery; in Vue you'll want to build all of that logic into components so the framework can do the work for you. I'd suggest making one Vue component for a link that manages its own state for open / closed / active etc, that recurses to its children only when "open". Then just call that once with the top of your nav data instead of trying to manage the whole tree directly after the fact as you would in jQuery.
Came across below statement in one or other form on google
Each time the underlying data changes in a React app, a new Virtual
DOM representation of the user interface is created.This is where
things get interesting. Updating the browser’s DOM is a three-step
process in React.
Whenever anything may have changed, the entire UI will be re-rendered
in a Virtual DOM representation.
The difference between the previous
Virtual DOM representation and the new one will be calculated.
The
real DOM will be updated with what has actually changed. This is very
much like applying a patch.
I am new to React and would like to understand above how above three points used to to work in pre-React Era say in jQuery (or native JS).
jQuery
HTML was constructed on server side, sent back to browser. Browser will parse, render, layout and paint it.
Say any new DOM element is created or hidden either on some user event or on load.
Will jQuery recreate the complete DOM? From third point stated above looks like React just update the DOM for only the part that has been changed but other system (primarily jQuery or native JS) will recreate the complete DOM. Is that correct?
Is the third point true only for DOM changes or even when state of any UI component changes like filling the text box/dropdown etc?
Will jquery recreate the complete DOM ? From third point stated above looks like React just update the DOM for only the part that has been changed but other system(primarily jquery or native js) will recreate the complete DOM. Is that correct?
jQuery
No, jQuery doesn't recreate the DOM. Instead it navigates the DOM tree with selectors provided to make the appropriate changes. This makes jQuery very similar to React, but its performance issues come with the way the code was designed and it's heavy usage of the facade design pattern. This is normal for any larger library that needs to support multiple browsers like Chrome, Firefox, Opera, etc.
Angular 1
A framework that used to repaint the entire DOM was Angular 1. The client would make some changes, and rerender whenever $scope.apply or $scope.digest was called. This, combined with a huge number of listeners on large pages for two way data-binding was one of the big reasons why Angular had to undergo significant changes to stay competitive. Angular 8 is probably equivalent to React, but one has seen more adoption then the other.
React
React only updates the DOM that was changed. This is part of its "secret sauce". Along with its component centric architecture and early adoption of one way data-binding, it's seen a lot of success. Arguably React is starting to get more bloated since there's such wide adoption. This is normal for any project that gets mainstream usage. It's only a matter of time until people view React as a ton of performance problems and we'll create a new framework.
Alternatives
There are even faster frameworks than React, such as Elm lang. Nothing ever beats pure Javascript (e.g. document.querySelector()) since at their core, all frameworks use it. At that point you start hitting other trade offs such as lack of external libraries you can depend on, or difficulty in maintaining large front end codebases.
Is the third point true only for dom changes or even when state of any UI component changes like filling the text box/drop down etc ?
For jQuery or pure JS the third point is not true. There's a custom on-click handler of some sort that will run a function that makes a small change.
For something like Angular, that could be true if there are changes to scope that trigger a repaint. The same applies for React. If your submit button is supposed to redirect you to a completely different page, it will basically be repainting the DOM.
in react js in reander it create virtual DOM compare with browser DOM and update browser DOM. Rather than having virtual DOM why not to update directly in browser DOM.
Performance. Reading/writing to DOM is very expensive. It is much faster to calculate changes on JS data structure and then just do minimal amount of changes on real DOM. Except for some special cases you can avoid reading browser DOM alltogether thats why react is so fast.
Check this simple benchmark as you can see reading is not expensive. Writing is also not expensive but reading and writing is crazy expensive. (updateNode function does reading and writing)
Image is taken from this talk which I really recommend.
The DOM is made up of nodes that are rendered by your browser. As your application receives input from the user, it has to change certain nodes in order to show it's response (Ex- A button turning blue from red when the user clicks on it). Now, DOM is not good at doing anything smart. So, any time anything changes, it will re-render every node from scratch. This is a costly process.
React adds the brains to DOM by telling the DOM which node to render and which node to leave as it was. (Ex- Except the button, everything else in the UI should not change). This is done by storing the state of your DOM in JS in the form of nested objects (Forming a tree like strcuture). Changes to specific parts of this object will help React figure out which part of the DOM tree actually needs to be re-rendered. This is done using the concept of immutability which is very nicely explained in the ReactJS docs. So it basically diffs the new object with the old one and tells the DOM to make changes to specific nodes ONLY, thus improving performance by many folds.
I have 2 JS variables. before and after. They contains the SAME html document, but have some modification. About 1%-10% change between them. I want to update the body from before to after. The variablesbefore and after are raw string.
I can do something like that:
document.documentElement.innerHTML=after
The problem is that if I render this way it not look good. The render takes time, and there is a white screen between the renders. I want to show the user 10 modification in a second (video of modifications)
So what I want to do. I want to search and find only the elements that changed only by analyze the HTML text of before and after.
My way of solution:
I can find the changes and the position in the text using Javascript Library for diff & match & patch.
The question is:
After I find the text changes. How to find only the elements who changed. I update only those elements.
I thought, maybe to create a range, that contains every change, and update the range, but how exactly to do that?
If anything unclear, please comment, I will explain better.
I found a very good library for it: https://github.com/patrick-steele-idem/morphdom
Lightweight module for morphing an existing DOM node tree to match a
target DOM node tree. It's fast and works with the real DOM—no virtual
DOM here!
Very easy to use, and doing exactly what I need
If I have understood your question correctly, then what I would have done is,
1) Make a new object (view Object) which will control the rendering of DOM elements. (Similar to MVC)
2) In this object, I would have created 3 functions.
a) init function (contains the event-handlers)
b) render1 function (which will contain elements in before element)
c) render2 function (which will contain elements in after element)
Whenever there is an event where I need to change the HTML of a class/id/body/document, I will change that in init function and call render2 function which contains the after element.
This should not give any error, however the browser has to work to render all the page, but rendering can be divided over multiple elements of document. So, whenever you need to render a part of document, make separate render functions.
p.s. there can be different approaches.
You must implement the LCS(Longest Common Subsequence). To understand better of this algorithm you can watch this youtube video. Also It's easier to first study Longest Common Substring.
I think I have a solution. virtual-dom can do the work for me. I can create two VTree, make a diff, and apply a patch.
From the documentation of virtual-dom:
virtual-dom is what I need.
Manual DOM manipulation is messy and keeping track of the previous DOM
state is hard. A solution to this problem is to write your code as if
you were recreating the entire DOM whenever state changes. Of course,
if you actually recreated the entire DOM every time your application
state changed, your app would be very slow and your input fields would
lose focus.
virtual-dom is a collection of modules designed to provide a
declarative way of representing the DOM for your app. So instead of
updating the DOM when your application state changes, you simply
create a virtual tree or VTree, which looks like the DOM state that
you want. virtual-dom will then figure out how to make the DOM look
like this efficiently without recreating all of the DOM nodes.
virtual-dom allows you to update a view whenever state changes by
creating a full VTree of the view and then patching the DOM
efficiently to look exactly as you described it. This results in
keeping manual DOM manipulation and previous state tracking out of
your application code, promoting clean and maintainable rendering
logic for web applications.
https://github.com/Matt-Esch/virtual-dom
I have a view containing of many sub-views, which have relatively heavy CSS properties. and I need to add them(about 10-30 depending on screen-width) to browser every time user changes the sort or the category.
In android we handle this heavy task of adding many views, by using the ListView which basically does the heavy lifting once and then reuses the view later on.
I wanted to know if there is anyway in javascript to cache the view so appending them to the parent would be a lot faster.
in my performance tests, it takes about 500ms to just append the view to the parent DOM. but if there is a way to reuse a cached DOM to make things faster, it would be a lot better.
thanks in advance
I assume that in your case, one sub-view is needed at one time.
So, this library might inspire you http://nexts.github.io/Clusterize.js/
The idea is keep your whole data model in window object and render part of it (associated with sub-view) when user sort or category.