React的思想
react是什么
react是開發(fā)出來用來促進(jìn)UI交互的,創(chuàng)建帶有狀態(tài)的、可復(fù)用的UI組件的IU庫(kù)
react不僅可以在瀏覽器端使用,還可以在服務(wù)器端使用,還可以兩端一起使用。
react的底層概念:運(yùn)用的是virtual DOM(虛擬DOM),然后根據(jù)UI組件的狀態(tài)變化,有選擇的渲染DOM的節(jié)點(diǎn)樹,盡可能的操作最少的DOM來更新組件。
虛擬DOM是怎么工作的
1.在Web開發(fā)中,需要將數(shù)據(jù)的變化實(shí)時(shí)反映到UI上,就需要對(duì)DOM進(jìn)行操作,但是復(fù)雜頻繁的DOM操作會(huì)產(chǎn)生性能瓶頸。所以DOM就引入了虛擬DOM的機(jī)制。
實(shí)際上,在React中,render方法得到的實(shí)際上不是真實(shí)的DOM節(jié)點(diǎn),而僅僅是輕量級(jí)的JavaScript對(duì)象,我們稱之為虛擬DOM.
2.虛擬DOM是React的一大亮點(diǎn),具有批處理(batching)和高效的Diff算法。無需擔(dān)心性能問題而毫無顧忌的隨時(shí)刷新整個(gè)頁面,由虛擬DOM來確保只對(duì)界面上真正變化的部分進(jìn)行實(shí)際的DOM操作。
了解React虛擬DOM的機(jī)制就可以更好的理解React組件的生命周期,而且對(duì)于進(jìn)一步優(yōu)化React組件的生命周期。
如果沒有虛擬DOM,就相當(dāng)于重置innerHTML,在數(shù)據(jù)變動(dòng)比較大的情況下,比較合理,但是如果只有一小部分?jǐn)?shù)據(jù)變化時(shí),也要重置整個(gè)innerHTML,這就造成了很大的浪費(fèi)。
兩者的比較
innerHTML: render html string + 重新創(chuàng)建所有的DOM元素
virtual DOM: render Virtual DOM + diff + 必要的DOM更新。
3.和DOM操作比起來,js計(jì)算還是非常便宜的。Virtual DOM + diff 顯然要比render string慢,但是后面的DOM操作就比較便宜了。
DOM完全不屬于JavaScript,也不在JavaScript引擎中,JavaScript實(shí)際上是一個(gè)獨(dú)立的引擎,而DOM其實(shí)是瀏覽器引出的一組讓JavaScript操作HTML文檔的API而已,在即時(shí)編譯的時(shí)代下,調(diào)用DOM的開銷是很大的,而Virtual DOM的執(zhí)行完全都在JavaScript引擎中,不存在這個(gè)開銷。
4.React.js相對(duì)于直接操作原生DOM有很大的性能優(yōu)勢(shì),很大程度上歸功于虛擬DOM的batching和diff,batching把所有的DOM操作搜集起來,一次性提交給真實(shí)的DOM,
什么是虛擬DOM
React中,將真實(shí)的DOM抽象成一個(gè)JavaScript對(duì)象,也就是虛擬DOM,比如構(gòu)造一個(gè)虛擬的DOM.
var element = {element: 'ul',props: {id: 'list'},children: [{element:'li',props:'li1',children:['這是第一個(gè)li']},{element:'li',props:'li2',children:['這是第二個(gè)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只是一個(gè)JavaScript對(duì)象表示的DOM結(jié)構(gòu),頁面上并沒有這個(gè)結(jié)構(gòu),可以根據(jù)這個(gè)ul構(gòu)建真正的<ul> Element.prototype.render = function(){var d = document.createElement(tagName);//獲取propsvar props = this.props;for (key in props) {var propValue = props[key];d.setAttribute(key,propValue);}//獲取childrenvar 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節(jié)點(diǎn),把它塞入文檔中,這樣body里面就有了真正的<ul>的DOM結(jié)構(gòu)。在React中,也有一個(gè)render函數(shù),當(dāng)React中有state轉(zhuǎn)移的過程,所以每次state有變化之后,就會(huì)觸發(fā)render函數(shù),重新構(gòu)造一個(gè)虛擬DOM樹,對(duì)比新舊DOM樹的差別,記錄下差別,然后只針對(duì)差異部分對(duì)應(yīng)的真實(shí)DOM進(jìn)行操作。先總結(jié)到這里,下一篇博客,詳細(xì)講解Diff算法。
轉(zhuǎn)載于:https://www.cnblogs.com/sminocence/p/8284115.html
總結(jié)
- 上一篇: Vim 在 windows 环境下的初步
- 下一篇: python模块之序列化模块