Virtual DOM
就是 虛拟DOM,是用 JS 對象描述 DOM 節點的資料,由 React 團隊推廣出來的。
虛拟DOM 是前端的網紅,是以也有很多開發者開始研究和搞辯論賽。
其實主要對比了使用虛拟DOM和直接操作真實DOM的差別。
在 React 中實作資料驅動視圖大概流程是這樣的:
資料發生變化 -> 通過diff算法判斷要更新哪些節點 -> 找到要更新的節點 -> 更新真實DOM
Vue 的資料更新原理其實也差不多,隻是實作方式和使用文法會有所不同。
diff算法 會根據資料更新前和更新後生成的虛拟DOM進行對比,隻有兩個版本的虛拟DOM存在差異時,才會更新對應的真實DOM。
使用虛拟DOM對比的方式會比直接對比真實DOM的效率高。
而且真實DOM身上挂載的屬性和方法非常多,使用虛拟DOM的方式去描述DOM節點樹會顯得更輕便。
但這也意味着每次資料發生變化時都要先建立一個虛拟DOM,并使用 diff算法 将新虛拟DOM與舊虛拟DOM進行比對,這個步驟會消耗一點性能和需要一點執行時間。
React 和其他虛拟 DOM 架構使用的差異算法很快。可以說,更大的開銷在于元件本身。看如下代碼:
function StrawManComponent(props) {
const value = expensivelyCalculateValue(props.foo);
return (
<p>the value is {value}</p>
);
}
因為您會
value
在每次更新時不小心重新計算,無論是否
props.foo
已更改。但是以看起來更良性的方式進行不必要的計算和配置設定是非常常見的:
function MoreRealisticComponent(props) {
const [selected, setSelected] = useState(null);
return (
<div>
<p>Selected {selected ? selected.name : 'nothing'}</p>
<ul>
{props.items.map(item =>
<li>
<button onClick={() => setSelected(item)}>
{item.name}
</button>
</li>
)}
</ul>
</div>
);
}
在這裡,我們正在生成一個新的虛拟
<li>
元素數組——每個都有自己的内聯事件處理程式——在每次狀态更改時,無論是否
props.items
已更改。是以虛拟DOM在性能方面的損耗還是比較大的,需要有很高的記憶體。
而 Svelte 在未使用虛拟DOM的情況下實作了響應式設計。