摘要:渲染過程我們都知道使用可以使得網(wǎng)頁的性能有很大的提高,本文具體探究它是通過什么樣的渲染機制做到的。也就是說如果父節(jié)點不同,將不會在去對比子節(jié)點。
React渲染過程
我們都知道使用React可以使得網(wǎng)頁的性能有很大的提高,本文具體探究它是通過什么樣的渲染機制做到的。
在頁面一開始打開的時候,React會調用render函數(shù)構建一棵Dom樹,在state/props發(fā)生改變的時候,render函數(shù)會被再次調用渲染出另外一棵樹,接著,React會用對兩棵樹進行對比,找到需要更新的地方批量改動。
Diff 算法這個過程中,比較兩棵Dom tree高效找出需要更新的地方是很重要的。React基于兩個假設:
兩個相同的組件產(chǎn)生類似的DOM結構,不同組件產(chǎn)生不同DOM結構
對于同一層次的一組子節(jié)點,它們可以通過唯一的id區(qū)分
發(fā)明了一種叫Diff的算法,它極大的優(yōu)化了這個比較的過程,將算法復雜度從O(n^3)降低到O(n)。
同時,基于第一點假設,我們可以推論出,Diff算法只會對同層的節(jié)點進行比較。如圖,它只會對顏色相同的節(jié)點進行比較。
也就是說如果父節(jié)點不同,React將不會在去對比子節(jié)點。因為不同的組件DOM結構會不相同,所以就沒有必要在去對比子節(jié)點了。這也提高了對比的效率。
下面,我們具體看下Diff算法是怎么做的,這里分為兩種情況考慮
節(jié)點類型不同
節(jié)點類型相同,但是屬性不同
不同節(jié)點類型對于不同的節(jié)點類型,react會基于第一條假設,直接刪去舊的節(jié)點,新建一個新的節(jié)點。
比如:
// 由shape1到shape2
React會直接刪掉A節(jié)點(包括它所有的子節(jié)點),然后新建一個B節(jié)點插入。
為了驗證這一點,我打印出了從shape1到shape2節(jié)點的生命周期,gitbub鏈接:
https://github.com/hhhuangqio...
感興趣的可以自己跑一跑代碼~
Shape1 : A is created A render C is created C render C componentDidMount A componentDidMount Shape2 : A componentWillUnmount C componentWillUnmount B is created B render C is created C render C componentDidMount B componentDidMount
由此可以看出,A與其子節(jié)點C會被直接刪除,然后重新建一個B,C插入。
相同節(jié)點類型當對比相同的節(jié)點類型比較簡單,react會對比它們的屬性,只改變需要改變的屬性
比如:
這兩個div中,react會只更新className的值
這兩個div中,react只會去更新color的值
列表比較// 列表一到列表二
從列表一到列表二,只是在中間插入了一個C,但是如果沒有key的時候,react會把B刪去,新建一個C放在B的位置,然后重新建一個節(jié)點B放在尾部。
你說什么就是什么咯?!不信的話,我們還是跑一邊代碼,看看生命周期驗證一下
列表一: A is created A render B is created B render A componentDidMount B componentDidMount 列表二: A render B componentWillUnmount C is created C render B is created B render A componentDidUpdate C componentDidMount B componentDidMount
當節(jié)點很多的時候,這樣做是非常低效的,所以我們需要給每個節(jié)點配一個key,讓react可以識別出來哪些節(jié)點是一樣的,不需要重新創(chuàng)建。
配上key之后,在跑一遍代碼看看,
A render C is created C render B render A componentDidUpdate C componentDidMount B componentDidUpdate
果然,配上key之后,列表二的生命周期就如我所愿,只在指定的位置創(chuàng)建C節(jié)點插入。
這里要注意的一點是,key值必須是穩(wěn)定(所以我們不能用Math.random()去創(chuàng)建key),可預測,并且唯一的。
React整個的渲染機制就是在state/props發(fā)生改變的時候,重新渲染所有的節(jié)點,構造出新的虛擬Dom tree跟原來的Dom tree用Diff算法進行比較,得到需要更新的地方在批量造作在真實的Dom上,由于這樣做就減少了對Dom的頻繁操作,從而提升的性能。
探索性能優(yōu)化但是,是不是真的需要對所有的節(jié)點都重新渲染一遍呢?
下一篇文章,我們將繼續(xù)探討這個問題~
參考文檔:
http://www.infoq.com/cn/artic...
https://facebook.github.io/re...
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84678.html
摘要:因為版本將真正廢棄這三生命周期到目前為止,的渲染機制遵循同步渲染首次渲染,更新時更新時卸載時期間每個周期函數(shù)各司其職,輸入輸出都是可預測,一路下來很順暢。通過進一步觀察可以發(fā)現(xiàn),預廢棄的三個生命周期函數(shù)都發(fā)生在虛擬的構建期間,也就是之前。 showImg(https://segmentfault.com/img/bVbweoj?w=559&h=300); 背景 前段時間準備前端招聘事項...
showImg(https://segmentfault.com/img/remote/1460000018716142?w=200&h=200); showImg(https://segmentfault.com/img/remote/1460000018716143);showImg(https://segmentfault.com/img/remote/1460000010953710);...
摘要:前端面試總結先說背景,本人年月畢業(yè),去年十月校招到今年月一直在做前端開發(fā)工作,年前打算換工作,就重新梳理下面試考點總結包含基礎,基礎,常見算法和數(shù)據(jù)結構,框架,計算機網(wǎng)絡相關知識,可能有的點很細,有的點很大,參考個人情況進行總結,方便對知識 前端面試總結 先說背景,本人2018年7月畢業(yè),去年十月校招到今年10月一直在做前端開發(fā)工作,年前打算換工作,就重新梳理下面試考點總結包含: ...
摘要:前端面試總結先說背景,本人年月畢業(yè),去年十月校招到今年月一直在做前端開發(fā)工作,年前打算換工作,就重新梳理下面試考點總結包含基礎,基礎,常見算法和數(shù)據(jù)結構,框架,計算機網(wǎng)絡相關知識,可能有的點很細,有的點很大,參考個人情況進行總結,方便對知識 前端面試總結 先說背景,本人2018年7月畢業(yè),去年十月校招到今年10月一直在做前端開發(fā)工作,年前打算換工作,就重新梳理下面試考點總結包含: ...
閱讀 1317·2021-10-27 14:14
閱讀 3574·2021-09-29 09:34
閱讀 2477·2019-08-30 15:44
閱讀 1715·2019-08-29 17:13
閱讀 2569·2019-08-29 13:07
閱讀 867·2019-08-26 18:26
閱讀 3342·2019-08-26 13:44
閱讀 3210·2019-08-26 13:37