React的思想
react是什麽
react是開發出來用來促進UI交互的,創建帶有狀態的、可復用的UI組件的IU庫
react不僅可以在瀏覽器端使用,還可以在服務器端使用,還可以兩端一起使用。
react的底層概念:運用的是virtual DOM(虛擬DOM),然後根據UI組件的狀態變化,有選擇的渲染DOM的節點樹,盡可能的操作最少的DOM來更新組件。
虛擬DOM是怎麽工作的
1.在Web開發中,需要將數據的變化實時反映到UI上,就需要對DOM進行操作,但是復雜頻繁的DOM操作會產生性能瓶頸。所以DOM就引入了虛擬DOM的機制。
實際上,在React中,render方法得到的實際上不是真實的DOM節點,而僅僅是輕量級的JavaScript對象,我們稱之為虛擬DOM.
2.虛擬DOM是React的一大亮點,具有批處理(batching)和高效的Diff算法。無需擔心性能問題而毫無顧忌的隨時刷新整個頁面,由虛擬DOM來確保只對界面上真正變化的部分進行實際的DOM操作。
了解React虛擬DOM的機制就可以更好的理解React組件的生命周期,而且對於進一步優化React組件的生命周期。
如果沒有虛擬DOM,就相當於重置innerHTML,在數據變動比較大的情況下,比較合理,但是如果只有一小部分數據變化時,也要重置整個innerHTML,這就造成了很大的浪費。
兩者的比較
innerHTML: render html string + 重新創建所有的DOM元素
virtual DOM: render Virtual DOM + diff + 必要的DOM更新。
3.和DOM操作比起來,js計算還是非常便宜的。Virtual DOM + diff 顯然要比render string慢,但是後面的DOM操作就比較便宜了。
DOM完全不屬於JavaScript,也不在JavaScript引擎中,JavaScript實際上是一個獨立的引擎,而DOM其實是瀏覽器引出的一組讓JavaScript操作HTML文檔的API而已,在即時編譯的時代下,調用DOM的開銷是很大的,而Virtual DOM的執行完全都在JavaScript引擎中,不存在這個開銷。
4.React.js相對於直接操作原生DOM有很大的性能優勢,很大程度上歸功於虛擬DOM的batching和diff,batching把所有的DOM操作搜集起來,一次性提交給真實的DOM,
什麽是虛擬DOM
React中,將真實的DOM抽象成一個JavaScript對象,也就是虛擬DOM,比如構造一個虛擬的DOM.
var element = {
element: ‘ul‘,
props: {
id: ‘list‘
},
children: [
{element:‘li‘,props:‘li1‘,children:[‘這是第一個li‘]},
{element:‘li‘,props:‘li2‘,children:[‘這是第二個li‘]}
]
}
//element.js
function Element(tagName,props,children){
this.tagName = tagName;
this.props = props;
this.children = children;
}
module.exports = function(tagName,props,children){
return new Element(tagName,props,children)
}
var el = require(‘./element‘);
var ul = el(‘ul‘,{id:‘ulist‘},[
el(‘li‘,{id:‘list1‘},[‘1list‘]),
el(‘li‘,{id:‘list2‘},[‘list2‘])
])
//ul只是一個JavaScript對象表示的DOM結構,頁面上並沒有這個結構,可以根據這個ul構建真正的<ul>
Element.prototype.render = function(){
var d = document.createElement(tagName);
//獲取props
var props = this.props;
for (key in props) {
var propValue = props[key];
d.setAttribute(key,propValue);
}
//獲取children
var children = this.children || [];
children.forEach(function(child){
// if (child instanceof Element){
// tnode = child.render();
// }
// else{
// tnode = document.createTextNode(child);
// }
var childEl = (child instanceof Element) ? child.render():document.createTextNode(child)
d.appendChild(childEl);
})
return d;
}
var ulRoot = ul.render();
document.body.appendChild(ulRoot);
//ulRoot是真正的DOM節點,把它塞入文檔中,這樣body裏面就有了真正的<ul>的DOM結構。
在React中,也有一個render函數,當React中有state轉移的過程,所以每次state有變化之後,就會觸發render函數,重新構造一個虛擬DOM樹,對比新舊DOM樹的差別,記錄下差別,然後只針對差異部分對應的真實DOM進行操作。先總結到這裏,下一篇博客,詳細講解Diff算法。
React的思想