国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - React - React Diff原理深入分析

React Diff原理深入分析

2022-03-08 16:39AkeAke React

這篇文章主要介紹了React Diff原理的相關資料,幫助大家更好的理解和學習使用React框架,感興趣的朋友可以了解下

在了解Diff前,先看下React的虛擬DOM的結構

這是html結構

<div id="father">
  <p class="child">I am child p</p>
  <div class="child">I am child div</div>
</div>

這是React渲染html時的js代碼   自己可以在babel上試試

React.createElement("div", {id: "father"}, 
    React.createElement("p", {class: "child"}, "I am child p"),             
    React.createElement("div", {class: "child"}, "I am child div")
);

由此可以看出這是一個樹結構

React Diff原理深入分析

React在調用render方法時會創建一顆樹(簡稱pre),在下一次調用render方法時會返回一顆不同的樹(簡稱cur)。React就會比較pre和cur這兩棵樹之間的差別來判斷如何高效的更新UI,保證當前UI與最新的樹cur保持同步。

為了高效更新UI,React在以下兩個假設的基礎上提出了一套O(n)的啟發算法:

1.兩個不同類型的元素會產生出不同的樹;

2.開發者可以通過設置 key 屬性,來告知渲染哪些子元素在不同的渲染下可以保存不變;

Diffing 算法

逐層比較

在對比兩棵樹時,React是逐層進行比較的,只會對相同顏色框內的DOM節點進行比較。

React Diff原理深入分析

首先比較兩棵樹的根節點,不同類型的根節點會有不同的形態。當根節點為不同類型的元素時,React 會拆卸原有的樹并且建立起新的樹。舉個例子,當一個元素從 <a> 變成 <img>,從 <Article> 變成 <Comment>,或從 <Button> 變成 <div> 都會觸發一個完整的重建流程。

//before
<div>
    <App/>
</div>
//after
<p>
    <App/>
</p>

React會銷毀App組件(該組件的子組件也全都銷毀),并且重新創建一個新的App組件(也包括App的子組件)。

如下的DOM結構轉換:

React Diff原理深入分析

React只會簡單的考慮同層節點的位置變換,對于不同層的節點,只有簡單的創建和刪除。當根節點發現子節點中A不見了,就會直接銷毀A;而當D發現自己多了一個子節點A,則會創建一個新的A作為子節點。因此對于這種結構的轉變的實際操作是:

A.destroy();
A = new A();
A.append(new B());
A.append(new C());
D.append(A);

雖然看上去這樣的算法有些“簡陋”,但是其基于的是第一個假設:兩個不同類型的元素會產生出不同的樹。根據React官方文檔,這一假設至今為止沒有導致嚴重的性能問題。這當然也給我們一個提示,在實現自己的組件時,保持穩定的DOM結構會有助于性能的提升。例如,我們有時可以通過CSS隱藏或顯示某些節點,而不是真的移除或添加DOM節點。

對比同類型的組件元素

當一個組件更新時,組件實例會保持不變,但是state或props中數據的變化會調用render從而改變該組件中的子元素進行更新。 

對比同一類型的元素

當對比兩個相同類型的 React 元素時,React 會保留 DOM 節點,僅比對及更新有改變的屬性。

<div className="before"  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

React 會先匹配兩個 <li>first</li> 對應的樹,然后匹配第二個元素 <li>second</li> 對應的樹,最后插入第三個元素的 <li>third</li> 樹。

如果只是簡單的將新增元素插入到表頭,那么更新開銷會比較大。比如:

<ul>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

<ul>
  <li>Connecticut</li>
  <li>Duke</li>
  <li>Villanova</li>
</ul>

React 并不會意識到應該保留 <li>Duke</li> 和 <li>Villanova</li>,而是會重建每一個子元素。這種情況會帶來性能問題。

Keys

為了解決上述問題,React 引入了 key 屬性。當子元素擁有 key 時,React 使用 key 來匹配原有樹上的子元素以及最新樹上的子元素。以下示例在新增 key 之后,使得樹的轉換效率得以提高:

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

現在 React 知道只有帶著 "2014" key 的元素是新元素,帶著 "2015" 以及 "2016" key 的元素僅僅移動了。所以只是創建了 key=2014的元素,并不會創建剩下的兩個元素。

所以key的取值最好不要使用數組的下標,因為數組的順序可能會發生變化,最好使用自身數據攜帶的唯一標識(id或是其它的屬性)。

1. 虛擬DOM中key的作用:
                    1). 簡單的說: key是虛擬DOM對象的標識, 在更新顯示時key起著極其重要的作用。

                    2). 詳細的說: 當狀態中的數據發生變化時,react會根據【新數據】生成【新的虛擬DOM】,  隨后React進行【新虛擬DOM】與【舊虛擬DOM】的diff比較,比較規則如下:

                                    a. 舊虛擬DOM中找到了與新虛擬DOM相同的key:
                                                (1).若虛擬DOM中內容沒變, 直接使用之前的真實DOM
                                                (2).若虛擬DOM中內容變了, 則生成新的真實DOM,隨后替換掉頁面中之前的真實DOM

                                    b. 舊虛擬DOM中未找到與新虛擬DOM相同的key
                                                根據數據創建新的真實DOM,隨后渲染到到頁面

2. 用index作為key可能會引發的問題:
                                1. 若對數據進行:逆序添加、逆序刪除等破壞順序操作:
                                                會產生沒有必要的真實DOM更新 ==> 界面效果沒問題, 但效率低。

                                2. 如果結構中還包含輸入類的DOM:
                                                會產生錯誤DOM更新 ==> 界面有問題。                                                
                                3. 注意!如果不存在對數據的逆序添加、逆序刪除等破壞順序操作,
                                        僅用于渲染列表用于展示,使用index作為key是沒有問題的。

以上就是React Diff原理深入分析的詳細內容,更多關于React Diff原理的資料請關注服務器之家其它相關文章!

原文鏈接:https://www.cnblogs.com/akei/p/14684980.html

延伸 · 閱讀

精彩推薦
  • ReactReact 非父子組件傳參的實例代碼

    React 非父子組件傳參的實例代碼

    React 主要用于構建UI,很多人認為 React 是 MVC 中的 V(視圖)。本文給大家介紹React 非父子組件傳參的相關知識,感興趣的朋友跟隨一起看看吧...

    愚公搬代碼6392022-03-08
  • ReactReact+Ant Design開發環境搭建的實現步驟

    React+Ant Design開發環境搭建的實現步驟

    這篇文章主要介紹了React+Ant Design開發環境搭建的實現步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    qq_3341488311862022-02-24
  • React如何使用Redux Toolkit簡化Redux

    如何使用Redux Toolkit簡化Redux

    這篇文章主要介紹了如何使用Redux Toolkit簡化Redux,幫助大家更好的理解和學習使用React框架,感興趣的朋友可以了解下...

    杭州程序員張張8992022-02-24
  • ReactReact antd tabs切換造成子組件重復刷新

    React antd tabs切換造成子組件重復刷新

    這篇文章主要介紹了React antd tabs切換造成子組件重復刷新,需要的朋友可以參考下...

    一堆亂碼4752022-02-22
  • React深入理解React Native核心原理(React Native的橋接(Bridge)

    深入理解React Native核心原理(React Native的橋接(Bridge)

    這篇文章主要介紹了深入理解React Native核心原理(React Native的橋接(Bridge),本文重點給大家介紹React Native的基礎知識及實現原理,需要的朋友可以參考下...

    Gavell9612022-02-23
  • ReactReact Fiber結構的創建步驟

    React Fiber結構的創建步驟

    這篇文章主要介紹了React Fiber結構的創建步驟,幫助大家更好的理解和學習使用React,感興趣的朋友可以了解下...

    光光同學221677582022-03-02
  • ReactReact Router 如何使用history跳轉的實現

    React Router 如何使用history跳轉的實現

    這篇文章主要介紹了React Router 如何使用history跳轉的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    香辣素毛肚9962022-02-24
  • React如何用react優雅的書寫CSS

    如何用react優雅的書寫CSS

    這篇文章主要介紹了如何用react優雅的書寫CSS,幫助大家更好的理解和學習使用react,感興趣的朋友可以了解下...

    ws_qy10202022-03-03
主站蜘蛛池模板: 91精品国产综合久久婷婷香蕉 | 日韩一区二区精品视频 | 日韩在线二区 | 亚洲精品日本 | 97色伦97色伦国产欧美空 | 日本免费精品视频 | 日韩在线视频播放 | 中文字幕 国产精品 | 日韩电影在线 | 韩日在线观看视频 | 久久久国产精品视频 | 成人av电影天堂 | 日韩和的一区二在线 | 色接久久| 亚洲一区有码 | 国产日产精品一区二区三区四区 | 羞羞视频在线 | 都市激情av | 黄色成人在线视频 | 国产精品国产三级国产aⅴ9色 | 久久久高清 | 亚洲成人一区二区三区 | 日本中文字幕在线电影 | 秋霞av亚洲一区二区三 | 欧美喷潮久久久xxxxx | 性色视频在线 | 81精品国产乱码久久久久久 | 精品久久久久久亚洲综合网 | 欧美精品一区视频 | 精品一区久久 | 爱操在线 | 亚洲精品一区二区三区在线观看 | 黑人中文字幕一区二区三区 | 综合久久综合 | 久久精品国产免费 | 亚洲电影在线 | 自拍偷拍av | 五月激情综合网 | 国产一区免费 | 亚洲精品大片 | www久久精品|