react是開發出來用來促進UI交互的,建立帶有狀態的、可複用的UI組件的IU庫
react不只能夠在瀏覽器端使用,還能夠在服務器端使用,還能夠兩端一塊兒使用。
react的底層概念:運用的是virtual DOM(虛擬DOM),而後根據UI組件的狀態變化,有選擇的渲染DOM的節點樹,儘量的操做最少的DOM來更新組件。html
1.在Web開發中,須要將數據的變化實時反映到UI上,就須要對DOM進行操做,可是複雜頻繁的DOM操做會產生性能瓶頸。因此DOM就引入了虛擬DOM的機制。
實際上,在React中,render方法獲得的實際上不是真實的DOM節點,而僅僅是輕量級的JavaScript對象,咱們稱之爲虛擬DOM.node
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更新。react
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,瀏覽器
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算法。app