学习 React:虚拟 DOM

2023-05-30 0 451

像打印机、表单和网络那般,人工智慧驱动力的 LLM 辅助工具可能会发生改变他们的组织工作形式,但不能发生改变人类文明依然是具体来说专门从事组织工作的人这一历史事实。

React 并非像 jQuery 那般间接操作形式 DOM,而要建立他们的分立 DOM。让他们看一看它是怎样组织工作的。

Zopfli学习 React:虚拟 DOM

据传DOM read/write 十分快,因而DOM element add/remove 十分快。但前述情形是 DOM 十分快,DOM 原素预览/删掉近似于 JS 中的第一类特性加进或删掉。但为何看上去DOM原素没有加速预览原因在于DOM发生改变后应用程序中的Render民主化。

让他们先看一看应用程序的组织工作业务流程。

学习 React:虚拟 DOM

在上图中,他们看见应用程序遵从两个关键步骤来表明文本。

具体来说,应用程序转交 HTML 文件格式,接着采用其图形发动机导出它并建立一个 DOM 树。在 DOM 树中,建立的 HTML 原素留存为结点。与 HTML 文件格式那般,应用程序采用 CSS 导出器导出 CSS 文件格式文本。导出后,它的建立近似于 CSS 的 DOM。它被称作 CSSOM。式样也留存为结点的边线。那些导出的 CSS 和 HTML 一同形成了图形树。此图形树介乎称作产业布局的期间。在此期,排序图形树座标并附带原素。因而在那个期,图形树保有大部份重要信息,如 HTML、式样和绘出原素的座标。后,依照图形树结点重要信息顺利完成绘出期。在最终期,网页表明给终端用户。

因而,当他们预览 DOM 中的任何人文本时,浏览器会再度再次运转该操作过程。大部份 HTML 原素的建立和定位、CSS 式样重要信息的再次排序都会再度顺利完成,接着再次绘出和表明网页。

尽管现代应用程序以十分快的形式执行那些操作形式,但为了更好的用户体验,目前大多数 Web 应用程序都是作为 SPA(单页应用程序)制作的。

在采用 SPA 时,他们必须处理大量的 DOM 操作形式。通常他们可以看见 Web 应用程序为单个操作形式进行 100 次 DOM 操作形式。🥹😭😩

学习 React:虚拟 DOM

当我们将进行那些大量的 DOM 操作形式时,它可能会在他们的应用程序中经过一段时间后受到影响。但无论怎样他们都必须这样做。😞 因而为了尽量减少对性能的影响,他们可以尝试这两个东西。

进行批量预览🤞尽量少做 DOM 操作形式 😀

让他们在这里看一个批量预览的例子。让他们具体来说建立一个 HTML 文件格式。

<!DOCTYPE html><html lang=”en”><head> <meta charset=”UTF-8″> <meta http-equiv=”X-UA-Compatible” content=”IE=edge”> <meta name=”viewport” content=”width=device-width, initial-scale=1.0″> <title>DOM</title></head><body> <div class=”container”> </div> <script src=”./dom.js”></script></body></html>

现在让他们建立dom.js文件格式。

let increment = 0;let container = document.querySelector(.container);// slowwhile (increment < 50000) { increment++; container.innerHTML += + increment;}

在dom.js文件格式中,他们可以看见他们正在container为 while 循环中的每个增量预览 html。因而这里 DOM 操作形式发生了 50000 次。这是很多!为此,网页在长时间等待后加载。

现在让他们预览 dom.js 文件格式。让他们建立一个空白数组,并将每个增量的数字推送到数组中。

let array = [];let increment = 0;let container = document.querySelector(.container);// fastwhile (increment < 50000) { array.push(++increment);}container.innerHTML = array.join( );

因而,在大部份原素都被推送到数组后,他们可以container采用 将数组原素放入 html中array.join( )。因而这只需要一个 DOM 操作形式,网页会立即加载。

从上面的例子中他们可以清楚地看见,由于过多的 DOM 操作形式,他们的网页加载缓慢。但通过简单的修改,他们可以在获得相同输出的同时实现更快的网页加载。这种形式称作batch update.

他们可以batch update不采用交互式 DOM 或 React。但如果他们只想为预览的原素预览 DOM,他们需要采用交互式 DOM。

为了实现那个 DOM 应该在预览原素之前和预览原素后有两个单独的快照。这样它就可以比较那些快照以检查预览的边线。

但采用 DOM 来顺利完成那个任务是困难的,它会产生问题,而且会占用大量资源,这可能会带来更多问题。因而 React 建立了 Virtual DOM 来实现那个特性。

学习 React:虚拟 DOM

那么什么是交互式DOM?

它是 React 的游乐场 DOM,React 在这里进行更改。

它的组织工作形式近似于应用程序 DOM,但这里没有重绘关键步骤。

此处仅建立/预览 JS 原素。大部份预览都在交互式 DOM 中顺利完成,因而 DOM 没有加进/预览原素的压力。🤗

交互式 DOM 是怎样组织工作的?他们可以将 Virtual DOM 视为一棵树。结点是不同的组件。如果结点的状态发生任何人变化,则它会建立一棵新树。在新树中,大部份更改的组件和新组件都是新建立的。

学习 React:虚拟 DOM

因而,在这种情形下,React 可以比较交互式 DOM 中的先前状态和新状态,以检查哪个边线的哪个原素发生了变化。有一种有效的算法可以比较前后的状态。该算法称作diffing或reconciliation算法。

现在让他们看一看在采用 Reactive 形式预览原素的两个示例中,普通 DOM 和交互式 DOM 是怎样组织工作的。

采用普通 DOM

让他们具体来说建立 HTML 文件格式。

index.html

<!DOCTYPE html><html lang=”en”><head> <meta charset=”UTF-8″> <meta http-equiv=”X-UA-Compatible” content=”IE=edge”> <meta name=”viewport” content=”width=device-width, initial-scale=1.0″> <title>DOM Tutorial</title> <link rel=”stylesheet” href=”./style.css”></head><body> <div class=”container”> <ul id=”fruits”></ul> <br> <p> <input type=”text” id=”input”> </p> <button id=”button” onclick=”addItem()”>Add Item</button> </div> <script src=”./dom.js”></script></body></html>

在HTML文件格式中他们可以看见原素有一个ul列表原素区域。

还有一个文本输入区域和按钮来加进项目。

现在让他们预览 dom.js 文件格式。

// Lets first declare the variablesconst display = document.getElementById(fruits);const button = document.querySelector(#button);let fruits = [mango, guava, apple, orange];

从上面的代码他们可以看见他们已经初始化了element 和display的变量。还为 的初始列表建立了一个数组。ulbuttonfruits

现在让他们建立一个函数init并调用以追加和fruits排序display.

const init = function () { display.innerHTML = ; let liElements = ; fruits.sort().forEach(fruit => { let item = document.createElement(li); item.textContent = fruit; liElements += item.outerHTML; }); display.innerHTML = liElements;}// Using appendChildconst init = function () { display.innerHTML = ; fruits.sort().forEach(fruit => { let item = document.createElement(li); item.textContent = fruit; display.appendChild(item); });}init();

在单击按钮期间,他们将调用 addItem 函数。因而现在让他们加进那个功能。

const addItem = function () { fruits.myPush(document.getElementById(input).value);}

在上面的代码中,他们看见新的输入值将作为参数传递给函数myPush。

他们需要将myPush函数建立为自定义数组原型函数。

Array.prototype.myPush = function (…a) { this.push(a[0]); init();}

在那个 Array.prototype.myPush 函数中,他们将原素推送到数组并调用该init函数。

因而这里是数组,如果他们采用thenfruits调用函数,则将作为参数传递,并将其推送到数组。🥳fruits.myPush(banana)bananafruits

现在让他们看一看当他们在 DOM 中加进任何人原素时,事物是怎样再次呈现的。

学习 React:虚拟 DOM

让他们具体来说在 Chrome 中打开开发辅助工具。从options->More tools选择Rendering。

学习 React:虚拟 DOM

接着从图形选项卡检查Paint Flashing。

学习 React:虚拟 DOM

接着在应用程序中打开index.html文件格式或者采用live server插件打开网页。现在让他们看一看图形是怎样顺利完成的。

Zopfli学习 React:虚拟 DOM

Zopfli学习 React:虚拟 DOM

从图形示例中他们可以看见,在任何人边线加进任何人原素时,大部份原素都在再次图形和再次绘出。😕

现在让他们采用React交互式 DOM 建立相同的项目。😎

具体来说让他们建立index.html文件格式。

<!DOCTYPE html><html lang=”en”><head> <meta charset=”UTF-8″> <meta http-equiv=”X-UA-Compatible” content=”IE=edge”> <meta name=”viewport” content=”width=device-width, initial-scale=1.0″> <title>DOM Tutorial</title> <link rel=”stylesheet” href=”./style.css”></head><body> <div id=”root”></div> <!– Load React. –> <script src=”https://unpkg.com/react@17/umd/react.development.js” crossorigin></script> <script src=”https://unpkg.com/react-dom@17/umd/react-dom.development.js” crossorigin></script> <!– Load our React component. –> <script src=”https://unpkg.com/@babel/standalone/babel.min.js”></script> <script type=”text/babel” src=”./fruits.js”></script></body></html>

现在让他们建立和修改fruits.js文件格式。他们将通过采用钩子进行跟踪来查看状态变化useState。

React useStateHook 允许他们跟踪功能组件中的状态。

const domContainer = document.querySelector(#root);const Fruits = () => { const [fruit, setFruit] = React.useState(); const [fruits, setFruits] = React.useState([mango, guava, apple, orange]);};

在上面他们可以看见他们创建了一个组件,Fruits他们在其中解构从 返回的值useState。

他们有两个const变量[fruit, setFruit]和[fruits, setFruits]。

这里fruit和fruits是当前状态,setFruit和setFruits是用于预览状态的函数。

的初始状态fruit是一个空字符串,React.useState()。

而 的初始状态fruits是一个水果数组,React.useState([mango, guava, apple, orange])。

现在让他们预览组件中的状态Fruits。

const domContainer = document.querySelector(#root);const Fruits = () => { const [fruit, setFruit] = React.useState(); const [fruits, setFruits] = React.useState([mango, guava, apple, orange]); return ( <div className=”container”> <ul id=”fruits”> {fruits.sort().map((fruit, index) => ( <li key={index}>{fruit}</li> ))} </ul> <br /> <p><input type=”text” value={fruit} onChange={(e) => setFruit(e.target.value)} /></p> <button onClick={() => setFruits([…fruits, fruit])}>Add Item</button> </div> );};ReactDOM.render(<Fruits />, domContainer)

从组件的返回区域他们可以看见他们正在预览按键输入和按钮点击期间的状态。现在让他们在应用程序中运转项目,看一看在采用 React state 时图形是怎样顺利完成的。

Zopfli学习 React:虚拟 DOM

Zopfli学习 React:虚拟 DOM

从顶部的结果示例中,他们可以看见 React 有效地预览了 DOM 中特定区域的状态和预览。

因而,从 React Virtual DOM 和应用程序 DOM 的示例中,他们可以说两者都很快,但 Virtual DOM 以更有效的形式组织工作,这就是为何它看上去组织工作得更快。🙌😍

举报/反馈

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务