React虛擬DOM
React框架的核心優勢之一就是支援建立虛擬DOM來提高頁面效能。
So, what is visual DOM?
先介紹一下實際DOM
設計人員在設計傳統HTML網頁的UI時,都會在頁面中定義若干的DOM元素,這些DOM元素就是所謂的實際DOM。通常,頁面中的實際DOM負責承載著外觀表現和資料變化,任何外觀形式的改變或資料資訊的更新都要反饋到UI上,都是需要通過操作實際DOM來實現的。
對於複雜的頁面UI而言,往往會定義大量的實際DOM。頻繁地操作大量的實際DOM,往往會帶來訪問效能的嚴重下降,使用者體驗也會隨之變差。React框架專門針對這個現象引入了虛擬DOM機制,以避免頻繁的DOM操作帶來的效能下降問題。
React框架將React DOM稱為虛擬DOM。
React DOM類似於一種將相關的實際DOM組合在一起的集合,是有區別於傳統概念上的DOM元素的,將其理解為DOM元件應該更為貼切。
下面分別以兩種DOM方式來實現一個效果相同的頁面,HTML DOM語法中的createElement()方法建立的是一個實際DOM,而React DOM中的createElement()方法建立的是一個虛擬DOM。
先看下HTML DOM語法中的createElement() 方法建立實際DOM的程式碼例項,
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>JavaScript createElement()</title> </head> <body> <!--新增文件主題內容--> <div id='id-div-react'></div> <script type="text/javascript"> //TODO: get div var divReact = document.getElementById('id-div-react'); //TODO: JavaScript DOM const jsSpan = document.createElement('span'); const jsH3 = document.createElement('h3'); jsH3.innerText = "JavaScript DOM"; const jsP = document.createElement('p'); jsP.innerText = "Create dom by JavaScript's createElement() func."; jsSpan.appendChild(jsH3); jsSpan.appendChild(jsP); divReact.appendChild(jsSpan); </script> </body> </html>
程式碼說明:
第09行程式碼通過<div id='id-div-react'>
標籤元素定義了一個層,用於顯示通過JavaScript建立實際DOM的容器。
第14~21行程式碼用於在層容器<div id='id-div-react'>
中建立實際DOM節點,具體內容如下:
第14行程式碼呼叫Document物件的createElement()方法,建立了一個元素節點。
第15~16行程式碼建立了一個<h3>
元素節點,並定義了文字內容。
第17~18行程式碼建立了一個<p>
元素節點,同樣定義了文字內容。
第19~20行程式碼分別呼叫appendChild()方法,將<h3>
<p>
元素節點填充進<span>
元素節點內。
第21行程式碼再次呼叫appendChild()方法,將<span>
元素節點填充進層容器<div id='id-div-react'>
內,從而實現建立實際DOM的操作。
效果圖如下所示:
再來看一下使用React DOM語法中的createElement()方法,以虛擬DOM方式實現的程式碼例項:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React createElement()</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!--Don't use this in production-->
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>
</head>
<body>
<!--新增文件主題內容-->
<div id='id-div-react'></div>
<script type="text/babel">
//TODO: get div
var divReact = document.getElementById('id-div-react');
//TODO: React DOM
const reactH3 = React.creatElement("h3", {}, "React DOM");
const reactP = React.creatElement("p", {}, "Create virsual DOM by React's createElement() func.");
const reactSpan = React.createElement("span", {}, reactH3, reactP);
ReactDOM.render(reactSpan, divReact);
</script>
</body>
</html>
第13行程式碼通過<div id='id-div-react'>
標籤元素定義了一個層,用於顯示通過React建立虛擬DOM的容器。
第14~22行定義的指令碼程式碼用於實現React虛擬DOM,具體內容如下:
第14行程式碼中的<script>
標籤元素內,type屬性型別定義為“text/babel”,表示內部的指令碼程式碼要使用React框架進行解析。
第16行程式碼先獲取了層<div id='id-div-react'>
容器物件(divReact)。
第18行和第19行程式碼呼叫ReactDOM物件的createElement()方法,分別建立了一個<h3>
元素節點(reactH3)和一個<p>
元素節點(reactP),並相應定義了文字內容。
第20行程式碼呼叫ReactDOM物件的createElement()方法,建立了一個<span>
元素節點(reactSpan),然後將剛剛建立的<h3>
元素節點(reactH3)和<p>
元素節點(reactP)填充進去。
第21行程式碼呼叫ReactDOM物件的render()方法,將<span>
元素節點(reactSpan)渲染到層<div id='id-div-react'>
容器物件(divReact)中進行顯示。