React Virtual Dom & Diff Algorithm

什么是Virtual DOM

Virtual DOM只是真實(shí)Dom的副本,它不是Javascript的標(biāo)準(zhǔn)概念,更像是專門為了React設(shè)計(jì)的概念,可以稱之為Virtual React DOM。它是一個(gè)節(jié)點(diǎn)樹(shù), 每個(gè)節(jié)點(diǎn)存儲(chǔ)了對(duì)應(yīng)節(jié)點(diǎn)的部分信息并且實(shí)現(xiàn)了React interfaces。部分與React相關(guān)的API也會(huì)存儲(chǔ)在Fiber結(jié)構(gòu)中,因此Fibers是Virtual DOM的組成部分。
節(jié)點(diǎn)樹(shù)主要是為了服務(wù)于Diff算法,最小化頁(yè)面更新,提升性能。

  1. 刷新頁(yè)面(比如通過(guò)setState)
  2. 生成節(jié)點(diǎn)樹(shù)
  3. Diff 算法
  4. 計(jì)算出minimal render operation
  5. render ( to DOM, iOS, or Android)
    以上第一步到第四步均屬于reconciler,第五步屬于renderer

Diff Algorithm

React 如何使本該是 O(n3)的計(jì)算優(yōu)化成O(n)

  1. 首先檢查同級(jí)節(jié)點(diǎn)類型,如果節(jié)點(diǎn)類型發(fā)生改變,直接全部重新生成, 而且銷毀之前的節(jié)點(diǎn),之前的節(jié)點(diǎn)組件及其所有子組件componentWillUnmount觸發(fā), 新組件及其所有子組件UNSAFE_componentWillMount ,componentDidMount相繼觸發(fā)
  2. 如果節(jié)點(diǎn)類型相同,檢查節(jié)點(diǎn)屬性,僅更新發(fā)生改變的節(jié)點(diǎn)
  3. 如果子節(jié)點(diǎn)是list,默認(rèn)情況下(沒(méi)有 key),React會(huì)按序比較兩個(gè)列表,比如,列表末尾插入,React僅插入一個(gè)節(jié)點(diǎn),若列表頭插入,React會(huì)修改所有節(jié)點(diǎn)。
  4. 如果子節(jié)點(diǎn)是list,并且存在key,React在比較列表是,不會(huì)按序比較,而且類似比較key-element。

Element List with Index Key

日常開(kāi)發(fā)時(shí),有的小伙伴會(huì)使用index作為key,這是不太好的習(xí)慣,主要是因?yàn)閮牲c(diǎn):

  1. 如上所說(shuō),使用index作為key,list一旦重排(中間插入,末尾插入,中間刪除,混序)皆會(huì)導(dǎo)致不必要的其他list item的更新,耗費(fèi)性能
  2. 對(duì)于一組uncontrolled input list,加入順序發(fā)生變化,但兩個(gè)list實(shí)際上看不出差別,因此React不會(huì)更新,那么頁(yè)面上顯示的input順序也不會(huì)更新 demo
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容