假如你的專案使用了React,你知道怎麼做效能優化嗎?
你知道為什麼React讓你寫shouldComponentUpdate或者React.PureComponent嗎?
你知道為什麼React讓你寫Immutable Data Structures嗎?
你知道為什麼React讓你在渲染列表時,一定要給每個子項加一個key嗎?
你知道為什麼React讓你在條件渲染時,不寫if而寫&&操作符或三元操作符嗎?
一切的答案都在Virtual DOM上!
只要你跟著我完成了這個手寫Virtual DOM的系列,上面的所有問題你都將得到解答,從此進入react高手的陣營!
現在當我們談virtual DOM (VDOM)的時候,通常會將React捆綁在一起談。可實際上VDOM並不是React創造的,React將這個概念拿過來以後融會貫通慢慢地成為目前前端最炙手可熱的框架之一。
什麼是VDOM?
首先我們都知道什麼是DOM(Document Object Model),簡單說就是將一個HTML文件抽象表達為樹結構。VDOM則是將DOM再抽象一層生成的簡化版js物件,這個物件也擁有DOM上的一些屬性,比如id, class等,但它是完全脫離於瀏覽器而存在的。
為什麼要用VDOM?
隨著前端技術的發展,現在的網頁應用變得越來越龐大,DOM樹也隨之變得複雜。當我們要修改DOM的某個元素時,我們需要先遍歷找個這個元素,然後才修改能修改。而且如果我們大量地去修改DOM,每次DOM修改瀏覽器就得重繪(repaint)頁面,有的時候甚至還得重排(reflow)頁面,瀏覽器的重排重繪是很損耗效能的。
React是怎麼用VDOM解決這個問題的呢?
- 首先,在React當我們要去修改資料的時候,我們會呼叫React提供的setState方法來修改資料;
- React根據新的資料生成一個新的VDOM,因為VDOM本質上只是一個普通的js物件,所以這個過程是很快的;
- 然後React拿著新生成VDOM和之前的VDOM進行對比(diff演算法),找出不同的地方(新增,刪除,修改),生成一個個的補丁(patches);
- 最後React把這些補丁一次性打到DOM上,完成檢視的修改。
原理其實還是很直觀的,但React到底是怎麼用程式碼實現的呢?其中最關鍵的一步是React是怎麼diff的?如果搞清楚了內部的實現原理,對於我們使用React來寫出效能更高的程式碼至關重要。所以今天我要手把手教大家怎麼從零開始實現VDOM。
我們的設計藍圖
我們將採用跟React類似的方式
- 使用JSX來編寫元件;
- 用Babel將JSX轉化為純js(類似hyperscript);
- 將hyperscript轉化成我們的VDOM;
- 將VDOM渲染到頁面,形成真實的DOM;
- 手動更新資料並手動觸發更新檢視操作(這部分是react做的,跟VDOM的實現無關,所以我們手動模擬一下);
- 重複步驟二和步驟三,得到新的VDOM;
- diff新VDOM和舊VDOM,得到需要修改真實DOM的patches;
- 把patches一次性打到DOM上,只更新DOM上需要更改的地方。
下面我們開始正式進入寫程式碼環節,建議大家開啟編輯器跟著我一步一步的敲程式碼。這樣手把手教你敲程式碼的的博主你去哪裡找?還不抓住這個千載難逢的機會????
專案結構
- index.html
- index.js(所有的邏輯都寫在這個檔案裡)
- .babelrc(babel的配置頁)
- package.json
- compiled.js (這個檔案是babel打包自己生成的,不需要自己寫)
大家可以新建一個目錄,然後新建1-4這四個檔案