<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # React中幾個核心的概念 ## 虛擬DOM(Virtual Document Object Model) ### DOM的本質是什么:(了解) >瀏覽器渲染引擎工作流程都差不多,大致分為5步,**創建DOM樹——創建StyleRules——創建Render樹——布局Layout——繪制Painting**?? ?第一步,用HTML分析器,分析HTML元素,**構建一顆DOM樹**(標記化和樹構建)。 ? ? 第二步,用CSS分析器,分析CSS文件和元素上的inline樣式,生成頁面的樣式表。 ? ? 第三步,將DOM樹和樣式表,關聯起來,構建一顆Render樹(這一過程又稱為Attachment)。每個DOM節點都有**attach方法,接受樣式信息**,返回一個render對象(又名renderer)。這些render對象最終會被構建成一顆Render樹。 ? ? 第四步,有了Render樹,瀏覽器開始布局,為每個Render樹上的節點確定一個在顯示屏上出現的精確坐標。 ? ? 第五步,Render樹和節點顯示坐標都有了,就調用每個節點**paint方法,把它們繪制**出來。? ? ? **DOM樹的構建是文檔加載完成開始的?**構建DOM數是一個漸進過程,為達到更好用戶體驗,渲染引擎會盡快將內容顯示在屏幕上。**它不必**等到整個HTML文檔解析完畢之后才開始構建render數和布局。 ? ? **Render樹是DOM樹和CSSOM樹構建完畢才開始構建的嗎?**這三個過程在實際進行的時候又不是完全獨立,而是會有交叉。會造成一邊加載,一遍解析,一遍渲染的工作現象。 ? ? **CSS的解析是從右往左逆向解析的**(從DOM樹的下-上解析比上-下解析效率高),**嵌套標簽越多,解析越慢。** ![](https://box.kancloud.cn/71dd56c7b207602dc6e99939c697325d_624x289.webp) ### JS操作真實DOM的代價 ????????用我們傳統的開發模式,原生JS或JQ操作DOM時,瀏覽器會從構建DOM樹開始從頭到尾執行一遍流程。在一次操作中,我需要更新10個DOM節點,瀏覽器收到第一個DOM請求后并不知道還有9次更新操作,因此會馬上執行流程,最終執行10次。 例如,第一次計算完,緊接著下一個DOM更新請求,這個節點的坐標值就變了,前一次計算為無用功。計算DOM節點坐標值等都是白白浪費的性能。即使計算機硬件一直在迭代更新,操作DOM的代價仍舊是昂貴的,頻繁操作還是會出現頁面卡頓,影響用戶體驗。 ### 為什么需要虛擬DOM,它有什么好處? ? Web界面由DOM樹(樹的意思是數據結構)來構建,當其中一部分發生變化時,其實就是對應某個DOM節點發生了變化, ????????虛擬DOM就是為了**解決瀏覽器性能問題**而被設計出來的。**如前**,若一次操作中有10次更新DOM的動作,虛擬DOM不會立即操作DOM,而是將這10次更新的diff內容保存到本地一個JS對象中,最終將這個JS對象一次性attch到DOM樹上,再進行后續操作,避免大量無謂的計算量。**所以,**用JS對象模擬DOM節點的好處是,頁面的更新可以先全部反映在JS對象(虛擬DOM)上,操作內存中的JS對象的速度顯然要更快,等更新完成后,再將最終的JS對象映射成真實的DOM,交由瀏覽器去繪制。 ### 實現虛擬DOM 例如一個真實的DOM元素如下 ```html <p title="段落">這是p標簽</p> ``` ```javascript { name:'p', props:{ title:"段落" }, children:['這是p標簽'] } ``` 再來描述下面的一個DOM ```html <p title="段落">這是p標簽 <span>這是span標簽</span></p> ``` 再來描述 ~~~html <p title="段落">這是p標簽 <span>這是span標簽</span></p> ~~~ ~~~javascript { name:'p', ?props:{ title:"段落" }, children:['這是p標簽', { name:'span', props:null, children:[’這是span標簽‘] } ] } ~~~ 我們來想一個問題 我們之前是p標簽里面有個span標簽,那么我們后面把span標簽刪除后,虛擬dom是如何執行的? 答: ```html <p title="段落">這是p標簽 <span>這是span標簽</span></p> ``` 當刪除單擊按鈕時想要刪除span標簽,不會直接刪除,而是先要生成右側新的(刪除掉span后)的虛擬DOM對象,和左側的虛擬DOM對象作對比,發現只是少了span元素,那么它在操作真實DOM的時候會一次性將之前的span元素刪除。 ![](https://box.kancloud.cn/d765333ff74db3c29f2e1bf92f372a12_774x335.jpg) ## Diff算法 * tree diff:新舊DOM樹,逐層對比的方式,就叫做 tree diff,每當我們從前到后,把所有層的節點對比完后,必然能夠找到那些 需要被更新的元素; * component diff:在對比每一層的時候,組件之間的對比,叫做 component diff;當對比組件的時候,如果兩個組件的類型相同,則暫時認為這個組件不需要被更新,如果組件的類型不同,則立即將舊組件移除,新建一個組件,替換到被移除的位置; * element diff:在組件中,每個元素之間也要進行對比,那么元素級別的對比,叫做 element diff; * key:key這個屬性,可以把 頁面上的 DOM節點 和 虛擬DOM中的對象,做一層關聯關系; ![](https://box.kancloud.cn/1f522dc11891365ce77c7650f517495a_736x409.png) 參考資料: https://www.jianshu.com/p/af0b398602bc [http://www.ruanyifeng.com/blog/2015/09/web-page-performance-in-depth.html](http://www.ruanyifeng.com/blog/2015/09/web-page-performance-in-depth.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看