Introduction
本学期选了“软件体系结构”这门课,结课作业是小组恢复React的软件体系结构。在Functional View部分,我负责了解React的虚拟DOM和Diff算法,下面是我的一些理解。(根据结题报告要求,以下内容大部分用英文呈现,本人英语水平有限,希望各位看官批评指正)
Virtual DOM
An Example
To begin with, let’s have a look at this code.
const title = <h1 className="title">Hello, world!</h1>;
This statement uses a new syntax name JSX, which allows us to write HTML segments within JavaScript code. In fact, the code above will be converted into the corresponding code below.
const title = React.createElement(
'h1',
{ className: 'title' },
'Hello, world!'
);
Traditional workflow of browser engines
- HTML Parser will analyze elements in HTML files to build a DOM Tree.
- CSS Parser will analyze CSS files and inline styles defined in them and generate a Style Table of the page.
- Attachment will link DOM Tree and Style Table above and create a Render Tree. Actually, each DOM node in the DOM Tree has a method named “attach” which get the style information and return an object of render. These objects of render will make up a Render Tree.
- Given the Render Tree, the browser will start to set the layout. Every node in the Render Tree will be allocated a precise coordinate on the screen.
- The method named “paint” of each node will be called to show the node.
Previously, when the DOM is modified, the browser will run the workflow above through, which can cost a lot of time. When there are ten modifications on the DOM, the browser will run the procedure ten times. However, as we all know, we can run the procedure to set ten modifications only in one time, while the computer cannot do that.
Virtual DOM is designed to solve this bottleneck. It can save the ten modifications in one local instance of JavaScript to avoid unnecessary cost of repeated updating of DOM Tree.
Diff Algorithm
We have learn that Virtual DOM normally resides in memory and begins with a copy of current DOM Tree. There comes a question, how can we make changes on the current DOM appear on the Virtual DOM Tree? Diff Algorithm works well in this case.
Algorithms comparing two trees have time complexity of O(n3). However, the time complexity of Diff algorithm is O(n), which compares trees layer by layer. Since in web programming DOM elements won’t be moved from layer to layer, this simplified algorithm works best.
There are four cases in our concern.
Case 1: REPLACE
When a node is changed, the old node will be replaced by the new one along its children. This method might have low efficiency especially when the children nodes remain the same.
Case 2: PROPS
When attributes of a node are changed, the node will be updated instead of being replaced. See the code below for an example.
renderA: <ul>
renderB: <ul class: 'marginLeft10'>
=> [addAttribute class "marginLeft10"]
Case 3: TEXT
When the text within a node is changed, just modify the text of that node.
Case 4: REORDER
This case involves moving, adding and deleting children nodes.
Let’s have a look at this example.
There are several ways to solve this problem.
The simplest way: delete C, add F, delete D, add C, delete E, add D, add E.
However, when we are writing codes in JSX, React reminds us that we should define keys for arrays and enumerations.
In this way, React can use key to locate the position and add node much more efficiently.