why updating the Real DOM is slow, what is Virtaul DOM, and how updating Virtual DOM increase the performance?

Updating a DOM is not slow, it is just like updating any JavaScript object; then what exactly makes updating Real DOM slow?

更新一个DOM其实并不慢,就像更新任意一个JS对象一样,那么到底是什么让更新DOM变得很慢呢?

Rendering engines which is responsible for displaying or rendering the webpage on the browser screen parses the HTML page to create DOM. It also parses the CSS and applies the CSS to the HTML creating a render tree, this process is called as attachment.

Rendering引擎负责展示和渲染网页,parse从语法上分析HTML页面来创建DOM,它也词法分析CSS,并且把CSS应用到HTML上来创建一个rendertree,这个过程叫attachment

So when we do,

document.getElementById('elementId').innerHTML = "New Value"

Following thing happens:

  1. Browser have to parses the HTML
  2. It removes the child element of elementId
  3. Updates the DOM with the “New Value”
  4. Re-calculate the CSS for the parent and child
  5. Update the layout i.e. each elements exact co-ordinates on the screen
  6. Traverse the render tree and paint it on the browser display

Recalculating the CSS and changed layouts uses complex algorithm and they effect the performance.

 

当给innerHTML赋值的时候,下面的事情发生了:

1.浏览器词法分析HTML

2.删除掉element的子元素

3.用new value来更新DOM

4.为父元素和子元素重新计算CSS

5.准确的协调更新layout

5.穿越整个rendertree并在浏览器中绘制

重新计算CSS和layout使用了复杂的算法并且影响performance

 

Thus updating a Real DOM does not involves just updating the DOM but, it involves a lot of other process.

Also, each of the above steps runs for each update of the real DOM i.e. if we update the Real DOM 10 times each of the above step will repeat 10 times. This is why updating Real DOM is slow.

因此更新一个真的DOM的话不光只是更新了DOM,还影响了不少其他的过程

同时,每一次真实DOM的更新,上面的过程就会运行一遍,如果我们更新真实DOM十次,上面的步骤就会重复10次,这就是为什么更新真实DOM很慢。

How Virtual DOM solves this problem?

虚拟DOM怎么解决这个问题?

 

What is virtual DOM?

什么是虚拟DOM?

Virtual DOM is in-memory representation of Real DOM. It is lightweight JavaScript object which is copy of Real DOM.

Updating virtual DOM in ReactJS is faster because ReactJS uses

  1. Efficient diff algorithm
  2. Batched update operations
  3. Efficient update of sub tree only
  4. Uses observable instead of dirty checking to detect change

虚拟DOM是内存中对真实DOM的标识,是非常轻量的JS对象(wichi is copy of Real DOM)

在ReactJS中更新虚拟DOM更快,因为ReactJS使用

   1.有效的diff算法

   2.分批处理的更新操作

   3.只对子树的有效更新

   4.使用可观察量,而不是通过脏检查来监测变化

AngularJS uses dirty checking to find the models which has changed. This dirty checking process runs in cycle after a specified time. As the application grows, checking the whole model reduces the performance and thus makes the application slow.

AugularJS使用脏检查来找到哪里的models有改变,脏检查在某个特定时间会循环的执行,当app变大后,检查整个模型会导致性能下降。

 

ReactJS uses observable’s to find the modified components. Whenever setState() method is called on any component, ReactJS makes that component dirty and re-renders it.

ReactJS使用observable(可观察量?)来找到有修改的组件,当setState()在某个组件中被调用时,ReactJS会make that component dirty 并且重绘它。

 

Whenever setState() method is called, ReactJS creates the whole Virtual DOM from scratch. Creating a whole tree is very fast so it does not affect the performance. At any given time, ReactJS maintains two virtual DOM, one with the updated state Virtual DOM and other with the previous state Virtual DOM.

ReactJS using diff algorithm compares both the Virtual DOM to find the minimum number of steps to update the Real DOM.

Finding minimum number of modifications between two trees have complexity in the order of O(n^3). But react uses heuristic approach with some assumptions which makes the problems to have complexity in the order of O(n).

当setState()被调用的时候,ReactJS会创建整个Virtual DOM,创建一个树非常快,并且不会怎么影响性能,在任何时候,ReactJS保持两个虚拟DOM,一个是更新后状态的VirtualDOM,另一个是之前状态的虚拟DOM

ReactJS 使用dff算法来比较两个virutalDOM 来找到更新的最少的步骤,来更新真实DOM

找两棵树间minimum number of modifications 的时间复杂度是O(n^3),但是React制定了一些启发性的策略,来让这个复杂度降到O(n)

 

ReactJS uses following steps to find the difference in both the Virtual DOM’s

ReactJS使用了下面的步骤来找找到两个Virtual DOM间的不同

    1. Re-render all the children if parent state has changed. If the state of a component has changed, then ReactJS re-renders all the child components even if child components are not modified. To prevent the unwanted re-render of the child components we can use shouldComponentUpdate() component life cycle method. This will further help in boosting the performance.
    2. Breadth First Search. ReactJS traverse the tree using BST. Consider the below tree. States of element B and H have changed. So when using BST ReactJS reached element B it will by default re-render the element H. This is the reason to use BST for tree traversal
    3. Reconciliation. It is the process to determine which parts of the Real DOM need to be updated. It follow below steps:

        1. Two elements of different types will produce different trees.
        2. The developer can hint at which child elements may be stable across different renders with a key prop.

      1.如果父亲的state改变了,重新渲染所有的孩子。如果一个组件的state改变了,ReactJS重新绘制所有的子组件即时子组件没有改变。 来防止不必要的重新渲染我们可以使用shouldComponentUpdate(),这可以大大的帮助提升性能。

       2.广度优先搜索,ReactJS使用广度优先搜索来遍历树,思考下面的树,B和H的state改变了,当使用广度优先搜索的时候,到了B的时候ReactJS会默认的重新渲染element H,这就是使用广度优先遍历的原因。

     3.一致性比较。这一步来决定真实DOM中的哪一部分会被更新,它遵循以下的步骤:

        1.两个不同类型的元素会产生不同的树

         2.通过key prop开发者可以hint 那些 在不同renders中依然 stable 的元素

 

Batch Update

ReactJS using the diff algorithm to find the minimum number of steps to update the Real DOM. Once it has these steps, it executes all the steps in one event loop without involving the steps to repaint the Real DOM. Thus, if there are more element which gets updated ReactJS will wait for the event loop to finish then, in bulk will updated the real DOM with all the updated elements.

Once all the steps are executed, React will repaint the Real DOM. This means during the event loop, there is exactly one time when the Real DOM is being painted. Thus all the layout process will run only on time for updating the real DOM.

 

 

成批的更新

ReactJS使用diff算法来找到更新真实DOM的最小步骤。一旦得到了这些步骤,它会在一个 event loop中执行所有这些步骤(而不会引发DOM重绘),因此,如果有很多element需要更新,ReactJS会通过 event loop 来处理这些事件,成批的来更新这些需要更新的真实DOM。

 

一旦所有的步骤完成,React会重绘虚拟DOM,这意味着在event loop中,真实DOM只会被绘制依次,因此为了更新real DOM,所有的layout处理只会运行一次。

 

 

猜你喜欢

转载自www.cnblogs.com/eret9616/p/8931451.html