<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          React Diff 算法

          時間:?2017-11-27閱讀:?1482標簽:?diff

          React 是 facebook 出的一個前端框架. 設計的關鍵處就是性能問題。在本文中,我主要是介紹 Diff 算法以及 React 渲染 ,這樣你可以更好的優化你的應用程序。


          Diff 算法

          再介紹算法之前,我們先來了解一下 react 是怎么工作的。

          var MyComponent = React.createClass({ 
              render: function() {
                  if (this.props.first) {
                      return <div className="first"><span>A Span</span></div>;
                  } else { 
                      return <div className="second"><p>A Paragraph</p></div>; 
                  } }
              });
          

          在你構思著要UI 的時候。要知道最重要的一點是:渲染的結果不是一個真實 DOM 。 只是個普通的 JavaScript 對象. 我們就把它叫做虛擬 DOM.

          React 將使用這個方法試著用最快捷的步驟從前一個渲染到下一個。例如, 如果我們掛載 , replace it with, 然后卸載它, DOM 的結果會是這種情況:

          None to first

          • Create node: A Span

          First to second

          • Replace attribute: className="first" by className="second"
          • Replace node: A Span by A Paragraph

          Second to none

          • Remove node: A Paragraph

          Level by Level

          可以看到,在任意兩棵樹上找到最少修改次數為 O(n^3)。 這不是我們想要的. React 就使用了一種簡單高效的方式來處理這個修改,為 O(n).

          React 只是一級一級的調用這棵樹。 在影響極小的性能代價下大大的降低來復雜度,在 Web 應用中移動不同的 DOM 樹是及其罕見的。 通常只會在子節點上進行橫向移動。


          List

          假設我們有一個組件,一次渲染五個組件并在下一次渲染時候插入在其中插入一個新組件。這樣很難比較這兩個列表中組件之間的映射關系

          默認情況下,React 會把前一個列表組件和下一個列表組件相關聯起來。你可以通過添加 key的方式,去幫助 React 找到映射。在實際中,這樣子元素就會容易的被找出來。


          Components

          通常,一個 React App 會有很多用戶自己定義的 div 元素,這樣元素構成一顆很復雜的樹。由于 React 只會比較有同一個類的組件,因此 diff 算法會帶一些額外的組件信息。

          例如假如是 is replaced by an, React 將刪除標題組件并創建一個新的組件。 我們不需要太多的時間來匹配兩個不太可能有相似之處的組件。


          Event Delegation

          在 DOM 節點上進行事件監聽會使程序變得緩慢而且會耗費大量的內存。 因此,React 就采用了事件委托的方式。React 更進一步的實現符合 W3C 標準的事件。 Internet Explorer 8 的事件錯誤已經成為歷史,所有事件名稱在瀏覽器中都是一致的。

          讓我解釋一下它是如何實現的。 單個事件偵聽器附加到文檔的根目錄。 當事件被觸發時,瀏覽器給我們目標 DOM 節點。 為了通過 DOM 傳播事件,React 將不會在虛擬 DOM 上迭代。

          相反,我們使用每個 Reac t組件都有唯一的 ID。 我們可以使用簡單的字符串操作來獲得所有父組件的 ID。 通過將事件偵聽器存儲在哈希映射中,我們發現它比將它們附加到虛擬 DOM 更好。 以下是通過虛擬DOM分派事件時發生的情況的示例。

          // dispatchEvent('click', 'a.b.c', event) clickCaptureListeners['a'](event); clickCaptureListeners['a.b'](event); clickCaptureListeners['a.b.c'](event); clickBubbleListeners['a.b.c'](event); clickBubbleListeners['a.b'](event); clickBubbleListeners['a'](event);
          

          瀏覽器為每個事件和每個偵聽器創建一個新的事件對象。 這有很好的性能,你可以保留事件對象的引用,甚至修改它。 但是,這意味著要進行大量的內存分配。 在啟動時反應分配這些對象的池。 每當需要事件對象時,都會從該池中重用。 這大大減少了垃圾收集。

          Rendering

          Batching

          每當你調用一個組件的 setState 時,React 就會把它標記為臟元素。 在事件循環結束時,React 查看所有有臟元素的組件并重新渲染它們。

          這個批處理意味著在一個事件循環期間,DOM 正在被更新。 這個屬性是構建高性能應用程序的關鍵。 在React應用程序中,默認情況下會使用它。


          Sub-tree Rendering

          當調用setState時,組件會重新建立其子組件虛擬 DOM。 如果你在根元素上調用setState,那么整個React應用程序就會被重新渲染。 所有的組件,即使它們沒有改變,都會調用它的“渲染”方法。 這聽起來可怕,效率低下,但在實踐中,這影響也不大,因為我們并沒有觸及到實際的DOM。。。。。(其實還是蠻大的啊,有些組件會多次渲染啊,shouldUpdate 優化)

          首先,我們正在討論顯示用戶界面。 由于屏幕空間有限,通常一次需要顯示數百到數千個元素的訂單。 幸好 JavaScript 已經有足夠快的業務反應,使得整個界面處于可管理狀態。

          另一個重要的一點是,在編寫 React 代碼時,最好每次改變時都不要在根節點上調用 setState。 您可以在接收到更改事件的組件或它的父組件上調用。你很少會在最頂端去處處理邏輯,這就意味著渲染只會發生在組件自己的節點上。


          Selective Sub-tree Rendering

          最后,你有可能阻止一些子樹重新渲染。 如果您在組件上實現以下方法:

          boolean shouldComponentUpdate(object nextProps, object nextState)
          

          基于組件的前一個和下一個狀態,你可以告訴 React 這個組件沒有改變,沒有必要重新渲染它。 如果執行得當,這可以給你巨大的性能改進。(還是應該從根本上去避免組件的渲染問題。。。把組件當作最好一個組件寫。。。。。)

          為了能夠使用它,你必須要比較 JavaScript 的對象。 如果淺比較的話,就會有很多問題提出來, 如果深的話我們應該使用不可變的數據結構或者做更深層的拷貝。

          而且你要記住,這個函數會一直被調用,所以你要確保計算花費的時間比啟發式計算所需的時間少,而不是渲染組件的時間, 渲染不是嚴格需要的。.


          Conclusion

          我們已經知道很長一段時間觸摸DOM是昂貴的,你應該批量寫和讀操作,事件委托更快...

          人們仍然在談論他們,因為在實踐中,他們很難在普通的JavaScript代碼中實現。 React的突出之處在于所有這些優化都是默認進行的。 這使得在腳下拍攝自己很難,并使您的應用程序變慢。

          React 的性能優化問題也很容易理解:每個setState重新渲染整個子樹。 如果要壓縮性能,請盡可能調用 setState,并使用shouldComponentUpdate 來防止重新渲染大型子樹。

          來源:原文鏈接 翻譯鏈接 


          站長推薦

          1.阿里云: 本站目前使用的是阿里云主機,安全/可靠/穩定。點擊領取2000元代金券、了解最新阿里云產品的各種優惠活動點擊進入

          2.騰訊云: 提供云服務器、云數據庫、云存儲、視頻與CDN、域名等服務。騰訊云各類產品的最新活動,優惠券領取點擊進入

          3.廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入

          鏈接: http://www.modern-decoration.com.cn/article/detial/179

          內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權或違規,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全運營推廣

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网