欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue中的虛擬DOM、diff算法、key的作用詳解

 更新時(shí)間:2025年04月01日 14:37:30   作者:貓老板的豆  
這篇文章主要介紹了Vue中的虛擬DOM、diff算法、key的作用,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、虛擬DOM

從本質(zhì)上來說,虛擬DOM是一個(gè)JavaScript對象,通過對象的形式來描述真實(shí)的DOM結(jié)構(gòu)。

將頁面的狀態(tài)抽象為JS對象的形式,配合不同的渲染工具,使跨平臺(tái)渲染成為可能。通過事務(wù)處理機(jī)制,將多次DOM修改的結(jié)果一次性的更新到頁面上,從而有效的減少頁面渲染的次數(shù),減少修改DOM的重繪重排次數(shù),提高渲染性能。

虛擬DOM本身是js對象,是對DOM的抽象,是更加輕量級的對 DOM的描述。

虛擬DOM流程

創(chuàng)建虛擬 DOM

當(dāng)組件被創(chuàng)建或更新時(shí),Vue 的渲染函數(shù)會(huì)返回一個(gè)新的虛擬 DOM 樹。

這個(gè)樹是一個(gè) JavaScript 對象,它描述了 真實(shí)DOM 的結(jié)構(gòu)、屬性和子元素。

// 真實(shí)dom
<ul id="list">
    <li class="item">哈哈</li>
    <li class="item">呵呵</li>
    <li class="item">嘿嘿</li>
</ul>

Vue會(huì)把代碼轉(zhuǎn)換成一個(gè)對象(虛擬 DOM),通過對象的形式來描述真實(shí)的DOM結(jié)構(gòu)

轉(zhuǎn)換成虛擬 DOM對象, 類似于下面這種(偽代碼)

let oldVDOM = { // 舊虛擬DOM
    tagName: 'ul', // 標(biāo)簽名
    props: { // 標(biāo)簽屬性
        id: 'list'
    },
    children: [ // 標(biāo)簽子節(jié)點(diǎn)
        {
            tagName: 'li', props: { class: 'item' }, text: '哈哈'
        },
        {
            tagName: 'li', props: { class: 'item' }, text: '呵呵'
        },
        {
            tagName: 'li', props: { class: 'item' }, text: '嘿嘿'
        },
    ]
}

比較虛擬 DOM

這時(shí)候,我修改一個(gè)li標(biāo)簽的文本:

<ul id="list">
    <li class="item">哈哈</li>
    <li class="item">呵呵</li>
    <li class="item">哈哈哈</li> // 修改
</ul>

這時(shí)候生成的新虛擬DOM為:

let newVDOM = { // 新虛擬DOM
    tagName: 'ul', // 標(biāo)簽名
    props: { // 標(biāo)簽屬性
        id: 'list'
    },
    children: [ // 標(biāo)簽子節(jié)點(diǎn)
        {
            tagName: 'li', props: { class: 'item' }, text: '哈哈'
        },
        {
            tagName: 'li', props: { class: 'item' }, text: '呵呵'
        },
        {
            tagName: 'li', props: { class: 'item' }, text: '哈哈哈'
        },
    ]
}
  • Vue會(huì)對比新舊虛擬DOM之間的差異,對比出是哪個(gè)虛擬節(jié)點(diǎn)更改了,找出這些差異。
  • 這個(gè)比較過程會(huì)找出兩個(gè)樹之間的最小變化集,即哪些節(jié)點(diǎn)需要被添加、更新或刪除。
  • 這個(gè)過程被稱為“diffing”或“差異算法”。Vue 的差異算法是高度優(yōu)化的,可以快速地計(jì)算出兩個(gè)樹之間的差異。

應(yīng)用更改:

一旦差異被計(jì)算出來:

  • Vue 就會(huì)只更新這些有差異的節(jié)點(diǎn)應(yīng)用到實(shí)際的 DOM 上,而不用更新其他數(shù)據(jù)沒發(fā)生改變的節(jié)點(diǎn),實(shí)現(xiàn)精準(zhǔn)地更新真實(shí)DOM,進(jìn)而提高效率。
  • 這個(gè)過程是批量的,意味著多個(gè)更改可以一次性地應(yīng)用到 DOM 上,從而減少了瀏覽器的重排和重繪次數(shù)。
  • 這個(gè)過程被稱為 Patch 或“打補(bǔ)丁

更新視圖:

當(dāng) DOM 更新完成后,瀏覽器就會(huì)重新渲染視圖,以反映組件的最新狀態(tài)。

虛擬DOM優(yōu)點(diǎn)

  • 性能優(yōu)化:通過減少對實(shí)際 DOM 的操作次數(shù),虛擬 DOM 可以顯著提高性能。
  • 跨平臺(tái):虛擬 DOM 使得 Vue.js 可以輕松地實(shí)現(xiàn)跨平臺(tái)應(yīng)用,例如使用 Web Workers 或 Weex 等技術(shù)來創(chuàng)建桌面應(yīng)用或移動(dòng)應(yīng)用。
  • 易于測試和調(diào)試:由于虛擬 DOM 是 JavaScript 對象,因此它可以使用 JavaScript 的所有調(diào)試工具進(jìn)行測試和調(diào)試。此外,你還可以使用諸如 Jest 或 Mocha 等測試框架來編寫針對虛擬 DOM 的單元測試。

用虛擬DOM算法操作真實(shí)DOM,性能高于直接操作真實(shí)DOM

虛擬DOM虛擬DOM算法是兩種概念:虛擬DOM算法 = 虛擬DOM + Diff算法

二、diff 算法 ??

上面的例子中,其實(shí)只有一個(gè)li標(biāo)簽修改了文本,其他都是不變的,所以沒必要所有的節(jié)點(diǎn)都要更新,只更新這個(gè)li標(biāo)簽就行,Diff算法就是查出這個(gè)li標(biāo)簽的算法。

Diff算法是一種對比算法。對比兩者是舊虛擬DOM新虛擬DOM,對比出是哪個(gè)虛擬節(jié)點(diǎn)更改了,找出這個(gè)虛擬節(jié)點(diǎn),并只更新這個(gè)虛擬節(jié)點(diǎn)所對應(yīng)的真實(shí)節(jié)點(diǎn),而不用更新其他數(shù)據(jù)沒發(fā)生改變的節(jié)點(diǎn),實(shí)現(xiàn)精準(zhǔn)地更新真實(shí)DOM,進(jìn)而提高效率。

  • 使用虛擬DOM算法的損耗計(jì)算: 總損耗 = 虛擬DOM增刪改+(與Diff算法效率有關(guān))真實(shí)DOM差異增刪改+(較少的節(jié)點(diǎn))排版與重繪
  • 直接操作真實(shí)DOM的損耗計(jì)算: 總損耗 = 真實(shí)DOM完全增刪改+(可能較多的節(jié)點(diǎn))排版與重繪

?? diff 算法是一種優(yōu)化手段:將新舊兩個(gè)虛擬 DOM 樹進(jìn)行差異對比,修補(bǔ)(更新)差異的過程叫做patch(打補(bǔ)丁),將更新補(bǔ)丁作用于真實(shí) DOM,以最小成本完成視圖更新。

  • Diff 算法:當(dāng)組件的數(shù)據(jù)發(fā)生變化時(shí),Vue.js 會(huì)創(chuàng)建一個(gè)新的虛擬 DOM 樹來反映這些變化。然后,它會(huì)使用 diff 算法來比較舊的虛擬 DOM 樹和新的虛擬 DOM 樹之間的差異。這個(gè)比較過程會(huì)找出兩個(gè)樹之間的最小變化集,即哪些節(jié)點(diǎn)需要被添加、更新或刪除。
  • Patch 過程(打補(bǔ)丁):在確定了需要更新的節(jié)點(diǎn)之后,Vue.js 會(huì)進(jìn)入 patch 過程。這個(gè)過程會(huì)將差異(或稱為“補(bǔ)丁”)應(yīng)用到實(shí)際的 DOM 上。通過只更新發(fā)生變化的節(jié)點(diǎn),Vue.js 可以避免不必要的 DOM 操作,從而提高性能。
  • 最小成本視圖更新:通過只更新發(fā)生變化的節(jié)點(diǎn),Vue.js 能夠在不重新渲染整個(gè)頁面的情況下更新視圖。這大大降低了瀏覽器的重排和重繪次數(shù),從而提高了頁面的性能。

為什么 vue ,react 這些框架中都會(huì)有 diff 算法呢?

要知道渲染真實(shí) DOM 的開銷是很大的,比如有時(shí)候我們修改了某個(gè)數(shù)據(jù),如果直接渲染到真實(shí) DOM 上會(huì)引起整個(gè) DOM 樹的重繪和重排,有沒有可能我們只更新我們修改的那一小塊 DOM 而不要更新整個(gè) DOM 呢?diff 算法能夠幫助我們。

當(dāng)數(shù)據(jù)發(fā)生變化時(shí),vue是怎么更新節(jié)點(diǎn)的?

我們先根據(jù)真實(shí) DOM 生成一棵 virtual DOM(虛擬DOM)樹,當(dāng) virtual DOM 某個(gè)節(jié)點(diǎn)的數(shù)據(jù)改變后會(huì)生成一個(gè)新的 Vnode(虛擬節(jié)點(diǎn)),然后 VnodeoldVnode 作對比,發(fā)現(xiàn)有不一樣的地方就直接修改在真實(shí)的 DOM 上,然后使 oldVnode 的值為Vnode

diff 的過程就是調(diào)用名為 patch 的函數(shù),比較新舊節(jié)點(diǎn),一邊比較一邊給真實(shí)的 DOM 打補(bǔ)丁。

diff算法流程

在Vue中,DIFF算法(也稱為差異算法或?qū)Ρ人惴ǎ┲饕糜诒容^新舊虛擬DOM(Virtual DOM)之間的差異,并基于這些差異來最小化地更新真實(shí)的DOM,從而提高頁面渲染的性能。

1. 虛擬虛擬DOM

Vue在渲染過程中,首先會(huì)創(chuàng)建一個(gè)虛擬的DOM樹(VNode),這個(gè)樹是對真實(shí)DOM的一個(gè)抽象表示。

當(dāng)數(shù)據(jù)發(fā)生變化時(shí),Vue會(huì)生成一個(gè)新的虛擬DOM樹,并與舊的虛擬DOM樹進(jìn)行比較。

2. 對比虛擬DOM

diff算法會(huì)比較新舊兩個(gè)虛擬DOM樹,找出它們之間的差異。這個(gè)比較過程是在同層級進(jìn)行的,不會(huì)跨層級比較。

比較過程中,Vue會(huì)采用一系列優(yōu)化策略,如雙指針、頭尾比較等,以提高效率。

  • Vue會(huì)比較新舊虛擬DOM節(jié)點(diǎn)的類型和屬性,以及它們的子節(jié)點(diǎn)。
  • 如果兩個(gè)節(jié)點(diǎn)相同(即類型和屬性都相同),則不需要進(jìn)行任何操作。
  • 如果節(jié)點(diǎn)類型不同,或者屬性發(fā)生了變化,Vue會(huì)創(chuàng)建一個(gè)新的DOM節(jié)點(diǎn)來替換舊的節(jié)點(diǎn)。
  • 對于子節(jié)點(diǎn)的比較,Vue會(huì)遞歸地應(yīng)用DIFF算法。

3. patch打補(bǔ)丁

一旦diff算法找出新舊虛擬DOM之間的差異,Vue會(huì)生成一個(gè)patch對象,這個(gè)對象記錄了需要執(zhí)行的DOM操作。

然后,Vue會(huì)遍歷這個(gè)patch對象,執(zhí)行相應(yīng)的DOM操作,更新真實(shí)的DOM。

diff算法優(yōu)化策略

1. 比較只會(huì)在同層級進(jìn)行, 不會(huì)跨層級比較

只會(huì)在同層級的節(jié)點(diǎn)之間進(jìn)行比較,不會(huì)跨層級比較。這大大減少了比較的次數(shù)和復(fù)雜度。

如果DOM節(jié)點(diǎn)出現(xiàn)了跨層級操作,Diff算法會(huì)簡單地視為刪除舊節(jié)點(diǎn)并創(chuàng)建新節(jié)點(diǎn),而不是嘗試去移動(dòng)節(jié)點(diǎn)。

<div>
    <p>123</p>
</div>
<div>
    <span>456</span>
</div>

上面的代碼會(huì)分別比較同一層的兩個(gè)div以及第二層的p和span,但是不會(huì)拿div和span作比較。

一張很形象的圖:(比較只會(huì)在同層級進(jìn)行, 不會(huì)跨層級比較)

概括起來就是對操作前后的dom樹同一層的節(jié)點(diǎn)進(jìn)行對比,一層一層對比,然后再插入真實(shí)的dom中,重新渲染

2. 深度優(yōu)先策略

diff算法在比較過程中采用深度優(yōu)先策略,深度優(yōu)先策略意味著算法會(huì)先盡可能深地搜索樹的分支,直到到達(dá)某個(gè)節(jié)點(diǎn)所在的最深位置,然后再回溯到上一層,繼續(xù)搜索其他分支。

當(dāng)比較兩個(gè)VNode時(shí),如果它們都有子節(jié)點(diǎn),那么diff算法會(huì)首先比較這兩個(gè)VNode的子節(jié)點(diǎn)。這個(gè)過程會(huì)遞歸地應(yīng)用深度優(yōu)先策略,先比較子節(jié)點(diǎn)的子節(jié)點(diǎn),直到到達(dá)樹的葉子節(jié)點(diǎn)。

3. 雙指針策略

雙指針策略是指在比較新舊VNode時(shí),同時(shí)設(shè)置兩個(gè)指針,一個(gè)指向舊VNode的頭部,另一個(gè)指向新VNode的頭部。這兩個(gè)指針會(huì)同時(shí)移動(dòng),以找出兩個(gè)VNode樹中的相同節(jié)點(diǎn)或差異。

  • 移動(dòng)指針:在比較過程中,如果當(dāng)前節(jié)點(diǎn)相同(即類型和屬性都相同),則兩個(gè)指針都會(huì)向后移動(dòng),繼續(xù)比較它們的子節(jié)點(diǎn)。
  • 節(jié)點(diǎn)復(fù)用:如果找到了相同的節(jié)點(diǎn),Vue會(huì)復(fù)用該節(jié)點(diǎn),而不是重新創(chuàng)建。這樣可以避免不必要的DOM操作,提高性能。
  • 處理差異:當(dāng)兩個(gè)指針指向的節(jié)點(diǎn)不同時(shí),Vue會(huì)根據(jù)差異類型進(jìn)行相應(yīng)的處理,如添加新節(jié)點(diǎn)、刪除舊節(jié)點(diǎn)或更新節(jié)點(diǎn)。

4. 頭尾比較

頭尾比較策略是在雙指針策略的基礎(chǔ)上的一種優(yōu)化。它同時(shí)從新舊VNode的頭部和尾部開始比較,以快速找到相同且不需要移動(dòng)的節(jié)點(diǎn)。

從兩頭向中間比較:從新舊VNode的頭部和尾部同時(shí)開始比較,如果找到相同的節(jié)點(diǎn),則將這些節(jié)點(diǎn)標(biāo)記為已處理,并繼續(xù)向中間移動(dòng)指針。

快速定位相同節(jié)點(diǎn):由于頭尾比較策略同時(shí)從兩端開始,因此可以更快地定位到相同且不需要移動(dòng)的節(jié)點(diǎn)。這樣可以減少不必要的比較和DOM操作,提高性能。

處理剩余節(jié)點(diǎn):當(dāng)頭部和尾部的指針相遇或交叉時(shí),表示已經(jīng)處理完了所有相同的節(jié)點(diǎn)。此時(shí),如果新VNode中還有剩余節(jié)點(diǎn),Vue會(huì)將這些節(jié)點(diǎn)添加到真實(shí)DOM的末尾;如果舊VNode中還有剩余節(jié)點(diǎn),Vue會(huì)將這些節(jié)點(diǎn)從真實(shí)DOM中刪除。

5. 跳過靜態(tài)節(jié)點(diǎn)

Vue會(huì)對模板中的靜態(tài)內(nèi)容進(jìn)行優(yōu)化,以減少更新時(shí)的性能消耗。

例如,如果一個(gè)節(jié)點(diǎn)的內(nèi)容是靜態(tài)的(即不會(huì)隨數(shù)據(jù)變化而變化),Vue會(huì)將其標(biāo)記為靜態(tài)節(jié)點(diǎn),并在后續(xù)的DIFF過程中跳過這些節(jié)點(diǎn)的比較。

通過以上優(yōu)化策略,diff算法可以更加高效地找出新舊VNode之間的差異,并以最小化的代價(jià)更新真實(shí)的DOM。這些優(yōu)化策略使得Vue在處理大量DOM更新時(shí)能夠保持較高的性能。

6. 唯一標(biāo)識(shí)key

詳見下文

三、vue for 循環(huán)中 key 的作用

key是給每一個(gè)vnode的唯一id,可以根據(jù)key,更準(zhǔn)確、 更快的找到對應(yīng)的vnode節(jié)點(diǎn)。幫助Vue跟蹤每個(gè)節(jié)點(diǎn)的身份,以便在數(shù)據(jù)改變時(shí)能夠高效地更新虛擬DOM。

在新舊虛擬DOM的對比過程中看是否能找到相同的key:

1.有相同的key:(Vue就會(huì)認(rèn)為它們是同一個(gè)節(jié)點(diǎn))

  • 若虛擬DOM中的內(nèi)容沒變,則直接復(fù)用之前的真實(shí)DOM
  • 若虛擬DOM中的內(nèi)容變了,則生產(chǎn)新的真實(shí)DOM,并替換掉舊的真是DOM

2.沒有相同的key:(Vue就會(huì)認(rèn)為是新節(jié)點(diǎn))

  • 根據(jù)數(shù)據(jù)創(chuàng)建新的真是DOM,隨后渲染到頁面

vue中列表循環(huán)需加:key="唯一標(biāo)識(shí)" 唯一標(biāo)識(shí)可以是 item 里面 id

因?yàn)関ue組件高度復(fù)用增加 Key 可以標(biāo)識(shí)組件的唯一性,那么 Key 是如何更高效的更新虛擬 DOM 的呢,我們看下面的例子:

<body>
  <div id="demo">
    <p v-for="item in items" :key="item">{{item}}</p>
  </div>
  <script src="../../dist/vue.js"></script>
  <script>
    // 創(chuàng)建實(shí)例
    const app = new Vue({
      el: '#demo',
      data: { items: ['a', 'b', 'c', 'd', 'e'] },
      mounted () {
        setTimeout(() => { 
          this.items.splice(2, 0, 'f')  // ['a', 'b', 'f', 'c', 'd', 'e']
       }, 2000);
     },
   });
  </script>
</body>

在不使用key的情況,vue會(huì)進(jìn)行這樣的操作:

分析下整體流程:

  1. 比較A,A,相同類型的節(jié)點(diǎn),進(jìn)行patch,但數(shù)據(jù)相同,不發(fā)生dom操作
  2. 比較B,B,相同類型的節(jié)點(diǎn),進(jìn)行patch,但數(shù)據(jù)相同,不發(fā)生dom操作
  3. 比較C,F(xiàn),相同類型的節(jié)點(diǎn),進(jìn)行patch,數(shù)據(jù)不同,發(fā)生dom操作
  4. 比較D,C,相同類型的節(jié)點(diǎn),進(jìn)行patch,數(shù)據(jù)不同,發(fā)生dom操作
  5. 比較E,D,相同類型的節(jié)點(diǎn),進(jìn)行patch,數(shù)據(jù)不同,發(fā)生dom操作
  6. 循環(huán)結(jié)束,將E插入到DOM中 一共發(fā)生了3次更新,1次插入操作

我們希望可以在B和C之間加一個(gè)F,diff 算法默認(rèn)執(zhí)行起來是這樣的:即把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很沒有效率?

所以我們需要使用key來給每個(gè)節(jié)點(diǎn)做一個(gè)唯一標(biāo)識(shí),Diff算法就可以正確的識(shí)別此節(jié)點(diǎn),找到正確的位置區(qū)插入新的節(jié)點(diǎn)。

當(dāng)為v-for渲染的列表項(xiàng)設(shè)置唯一的key時(shí),Vue能夠準(zhǔn)確地識(shí)別每個(gè)列表項(xiàng)的身份。 

當(dāng)列表數(shù)據(jù)發(fā)生變化時(shí),Vue會(huì)根據(jù)key來判斷哪些列表項(xiàng)是新添加的、哪些是被刪除的、哪些是需要更新的。 這有助于Vue進(jìn)行高效的DOM更新操作,只更新需要改變的部分,而不是重新渲染整個(gè)列表。

當(dāng)我們在使用v-for時(shí),需要給單元加上key:

  • 如果不用key,Vue會(huì)采用就地復(fù)地原則:最小化element的移動(dòng),并且會(huì)嘗試盡最大程度在同適當(dāng)?shù)牡胤綄ο嗤愋偷膃lement,做patch或者reuse。
  • 如果使用了key,Vue會(huì)根據(jù)keys的順序記錄element,曾經(jīng)擁有了key的element如果不再出現(xiàn)的話,會(huì)被直接remove或者destoryed
  • 用+new Date()生成的時(shí)間戳作為key,手動(dòng)強(qiáng)制觸發(fā)重新渲染
  • 當(dāng)擁有新值的rerender作為key時(shí),擁有了新key的Comp出現(xiàn)了,那么舊key Comp會(huì)被移除,新key Comp觸發(fā)渲染

四、Vue 2 與 Vue3 中的區(qū)別

在 Vue 2 中:

  • 使用了虛擬 DOM 的技術(shù)來優(yōu)化 DOM 操作。當(dāng)數(shù)據(jù)變化時(shí),Vue 會(huì)生成一個(gè)新的虛擬 DOM 樹,并與舊的虛擬 DOM 樹進(jìn)行比較(這個(gè)過程通常稱為“diff”)。如果發(fā)現(xiàn)有差異,Vue 就會(huì)更新真實(shí)的 DOM。
  • 在 Vue 2 的實(shí)現(xiàn)中,這種比較是遞歸進(jìn)行的,會(huì)遍歷整個(gè)虛擬 DOM 樹,即使只有很少的部分發(fā)生了變化。這種策略在某些情況下可能會(huì)導(dǎo)致較高的計(jì)算復(fù)雜度。
  • ? 補(bǔ)充:雖然理論上要遍歷全樹,但實(shí)際通過同層比較和 key 優(yōu)化可以跳過部分子樹,并非完全無優(yōu)化。

在 Vue3 中:

區(qū)塊樹(Block Tree) 是Vue 3中引入的一種重要的優(yōu)化機(jī)制,它是Vue 3編譯器在解析模板時(shí)生成的一種樹狀結(jié)構(gòu),它基于模板中的代碼邏輯將模板劃分為多個(gè)區(qū)塊(Block)。

區(qū)塊樹的主要功能是在渲染時(shí)優(yōu)化DOM操作,它可以將模板中的靜態(tài)內(nèi)容和動(dòng)態(tài)內(nèi)容區(qū)分開,從而在更新時(shí)只關(guān)注那些實(shí)際發(fā)生變化的動(dòng)態(tài)內(nèi)容。 通過減少不必要的渲染開銷來提高性能。

  • 模板解析:Vue 3編譯器首先會(huì)將模板解析成抽象語法樹(AST),然后遍歷AST,找出其中的連續(xù)節(jié)點(diǎn)塊(Block),并對這些節(jié)點(diǎn)塊進(jìn)行分析和整理,最終形成一個(gè)區(qū)塊樹。
  • 靜態(tài)提升(Hoist Static) :在構(gòu)建區(qū)塊樹的過程中,Vue 3會(huì)將靜態(tài)節(jié)點(diǎn)(即不會(huì)改變的節(jié)點(diǎn))提升到渲染函數(shù)之外,從而減少了在每次渲染時(shí)都需要重新創(chuàng)建這些節(jié)點(diǎn)的開銷,徹底避免重復(fù) diff。
  • 標(biāo)記動(dòng)態(tài)節(jié)點(diǎn)類型(PatchFlags ):對于動(dòng)態(tài)節(jié)點(diǎn),Vue 3會(huì)在區(qū)塊樹中標(biāo)記它們的變化類型(例如,屬性更新、子節(jié)點(diǎn)更新等)。
  • 這些標(biāo)記可以在創(chuàng)建虛擬 DOM 節(jié)點(diǎn)時(shí)生成,并在后續(xù)的 diff 過程中使用。由于有了這些標(biāo)記,Vue 3 在進(jìn)行 diff 時(shí)就可以更有針對性地比較那些實(shí)際發(fā)生變化的節(jié)點(diǎn),根據(jù)這些標(biāo)記快速定位到需要更新的節(jié)點(diǎn),并只對這些節(jié)點(diǎn)進(jìn)行更新,而無需遍歷整個(gè)樹。這顯著減少了比較的范圍和計(jì)算量,從而提高了更新性能。

綜上:

  • 將純靜態(tài)節(jié)點(diǎn)提升到渲染函數(shù)外部,避免重復(fù)創(chuàng)建和比較;
  • 對動(dòng)態(tài)節(jié)點(diǎn)標(biāo)記 PatchFlags 標(biāo)識(shí)其變化類型(如文本/屬性/子節(jié)點(diǎn));
  • 配合區(qū)塊樹結(jié)構(gòu)記錄動(dòng)態(tài)子節(jié)點(diǎn)位置。
  • 在 diff 過程中,Vue 3 能夠跳過靜態(tài)節(jié)點(diǎn),并根據(jù) PatchFlags 僅對動(dòng)態(tài)節(jié)點(diǎn)的特定屬性進(jìn)行靶向比對,從而大幅降低計(jì)算復(fù)雜度。

舉例:

<!-- 模板 -->
<div>
  <span>Static</span>         <!-- 靜態(tài)提升(Hoist Static) -->
  <span :class="cls"></span>  <!-- 標(biāo)記動(dòng)態(tài)節(jié)點(diǎn)類型(PatchFlags ) class -->
  <span>{{ text }}</span>     <!-- 標(biāo)記動(dòng)態(tài)節(jié)點(diǎn)類型(PatchFlags ) text-->
</div>
  • Vue 2:比對 3 個(gè) 的所有屬性+子節(jié)點(diǎn)
  • Vue 3:完全跳過第一個(gè)靜態(tài) span,僅比對第二個(gè) span 的 class 屬性和第三個(gè) span 的文本內(nèi)容

這種機(jī)制使得 Vue 3 在具有大量靜態(tài)內(nèi)容+局部動(dòng)態(tài)更新的場景下,性能優(yōu)勢尤為明顯。

不建議用index作為key

不建議 用 index 作為 key,和沒寫基本上沒區(qū)別,因?yàn)椴还苣銛?shù)組的順序怎么顛倒,index 都是 0, 1, 2 這樣排列,導(dǎo)致 Vue 會(huì)復(fù)用錯(cuò)誤的舊子節(jié)點(diǎn),做很多額外的工作,效率底。

  • 用key會(huì)出問題:對數(shù)據(jù)進(jìn)行破壞順序的的操作(如:在數(shù)組前面或中間添加、刪除數(shù)據(jù))
  • 用key不會(huì)出問題:沒有對數(shù)據(jù)進(jìn)行破壞順序的的操作(如:在數(shù)組最后面添加、刪除數(shù)據(jù))

建議key用唯一標(biāo)識(shí),如:id、手機(jī)號(hào)、學(xué)號(hào)等

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue3.0使用ref和reactive來創(chuàng)建響應(yīng)式數(shù)據(jù)

    Vue3.0使用ref和reactive來創(chuàng)建響應(yīng)式數(shù)據(jù)

    ref?和?reactive?是?Composition?API?中用來創(chuàng)建響應(yīng)式數(shù)據(jù)的兩個(gè)核心函數(shù),在本篇文章中,我們將詳細(xì)講解如何使用?ref?和?reactive?來創(chuàng)建響應(yīng)式數(shù)據(jù),并展示它們之間的區(qū)別和使用場景,需要的朋友可以參考下
    2024-11-11
  • 詳解vue中$router和$route的區(qū)別

    詳解vue中$router和$route的區(qū)別

    這篇文章主要介紹了vue中$router和$route的區(qū)別,對vue感興趣的同學(xué),一定要看下
    2021-05-05
  • 在Vue環(huán)境下利用worker運(yùn)行interval計(jì)時(shí)器的步驟

    在Vue環(huán)境下利用worker運(yùn)行interval計(jì)時(shí)器的步驟

    這篇文章主要介紹了在Vue環(huán)境下利用worker運(yùn)行interval計(jì)時(shí)器的步驟,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 在Vue3中使用provide和inject進(jìn)行依賴注入的代碼詳解

    在Vue3中使用provide和inject進(jìn)行依賴注入的代碼詳解

    在現(xiàn)代前端開發(fā)中,Vue.js已經(jīng)成為了非常流行的框架之一,它提供了極大的靈活性和可維護(hù)性,今天我們要探討的是Vue?3中的provide和inject功能,這是一種用于在組件樹中進(jìn)行依賴注入的方法,需要的朋友可以參考下
    2024-06-06
  • Vue中的組件詳談

    Vue中的組件詳談

    這篇文章主要介紹了Vue的組件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-10-10
  • vue中Bootstrap的詳細(xì)使用方法

    vue中Bootstrap的詳細(xì)使用方法

    Bootstrap適用于快速搭建簡單網(wǎng)站或Web應(yīng)用程序的情況,而Vue.js適用于構(gòu)建復(fù)雜的單頁面應(yīng)用程序,根據(jù)您的項(xiàng)目需求和開發(fā)方式,您可以選擇使用Bootstrap、Vue.js或兩者結(jié)合使用,這篇文章主要介紹了vue使用Bootstrap的詳細(xì)方法,需要的朋友可以參考下
    2023-08-08
  • vue-cli項(xiàng)目中img如何使用require動(dòng)態(tài)獲取圖片

    vue-cli項(xiàng)目中img如何使用require動(dòng)態(tài)獲取圖片

    這篇文章主要介紹了vue-cli項(xiàng)目中img如何使用require動(dòng)態(tài)獲取圖片,具有很好的參考價(jià)值,希望對大家有所幫助。
    2022-09-09
  • Vue中在data里面調(diào)用method方法的實(shí)現(xiàn)

    Vue中在data里面調(diào)用method方法的實(shí)現(xiàn)

    這篇文章主要介紹了Vue中在data里面調(diào)用method方法的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vite創(chuàng)建vue3項(xiàng)目頁面引用public下js文件失敗解決辦法

    vite創(chuàng)建vue3項(xiàng)目頁面引用public下js文件失敗解決辦法

    Vue3相較于之前的版本有了不少變化,如引用全局Js文件,這篇文章主要給大家介紹了關(guān)于vite創(chuàng)建vue3項(xiàng)目頁面引用public下js文件失敗的解決辦法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • vue函數(shù)防抖與節(jié)流的正確使用方法

    vue函數(shù)防抖與節(jié)流的正確使用方法

    防抖和節(jié)流的作用都是防止函數(shù)多次調(diào)用,下面這篇文章主要給大家介紹了關(guān)于vue函數(shù)防抖與節(jié)流的正確使用方法,需要的朋友可以參考下
    2021-05-05

最新評論