今天我們要來延續昨天的提到的 DOM 為人詬病的效能問題,來討論 React 是如何透過 reconciliation 來解決這個問題的!我們都知道 DOM 在操作時會對效能造成很大的影響,但更精確的說法,應該是 DOM 操作所引發的 reflow 和 repaint 是非常耗效能的。 實際的介紹我在我的筆記裡面有提過,有興趣的可以去看看!這篇我們會 focus 在 React 的部分。那首先,我們要先來了解什麼是Virtual DOM!
Virtual DOM 是 React 所建立的一個虛擬的 DOM tree,透過物件的格式來描述 DOM 的結構並儲存在內存裡。當 Virtual DOM 更動時,不直接修改 DOM,而是先透過 diff 演算法比較 Virtual DOM 修改前與修改後的樹狀結構,然後批次更新真實 DOM 中的節點,來達到兩個優勢,
所以完整的 Virtual DOM 顯示的過程會是這樣的,
你看到這裡,你可能會開始好奇了,什麼是 diffing 演算法呢?
diffing 演算法用於比對兩顆 Virtual DOM 之間的差別,來找出變動的地方。他在執行時,有幾個重點:
像是以下的兩個 DOM tree,root element 從div
變成span
,這時就算中間的 component 是一樣的,但還是會被銷毀,然後重新建立一個 DOM tree
// 舊tree
<div>
<Counter />
</div>
//新tree
<span>
<Counter />
</span>
當比對以下兩個 DOM tree 時,因為他們的 root element 一樣,這時候就只要更新有變動的 attribute!
// 舊tree
<div className="before" title="stuff" />
//新tree
<div className="after" title="stuff" />
這裡簡單講了兩個 diffing 比較的重點,更多的細節可以在這裡看到 react docs
在了解 Virtual-DOM 和 diffing 演算法,我們來總結一下,**react 透過 diffing 演算法 更新 Virtual-DOM 和 DOM 來解決 DOM 的變動很耗能的問題。而這個過程,就叫做 reconciliation。**到這裡,我們終於知道 React 為什麼可以如此有效率跟快速了!下一篇我們會開始講實際應用到的層面,hooks。
:reconciliation 指的是 react 更新 Virtual-DOM 和 DOM 的過程,透過只更新有更動的部分,讓 React 可以比操作原生 DOM 更省效能跟快速。
https://www.geeksforgeeks.org/reactjs-reconciliation/
面試題 1. 什麼是 reconciliation?
面試題 2. 什麼是 Virtual-DOM?
面試題 1. 什麼是 diffing 演算法?
https://segmentfault.com/a/1190000039682751
https://tw.alphacamp.co/blog/dom-and-virtual-dom
https://cloud.tencent.com/developer/article/1882296
https://tech-blog.cymetrics.io/posts/mingyou/deep-dive-into-react-fiber/