虛擬DOM性能優化實戰,同樣是操作DOM,爲什麼說他快?

爲什麼說虛擬DOM快?

虛擬DOM不會進行排版與重繪操作
虛擬DOM進行頻繁修改,然後一次性比較並修改真實DOM中需要改的部分(注意!),最後並在真實DOM中進行排版與重繪,減少過多DOM節點排版與重繪損耗
真實DOM頻繁排版與重繪的效率是相當低的
虛擬DOM有效降低大面積(真實DOM節點)的重繪與排版,因爲最終與真實DOM比較差異,可以只渲染局部(同2)
使用虛擬DOM的損耗計算:
總損耗=虛擬DOM增刪改+(與Diff算法效率有關)真實DOM差異增刪改+(較少的節點)排版與重繪
直接使用真實DOM的損耗計算:
總損耗=真實DOM完全增刪改+(可能較多的節點)排版與重繪
總之,一切爲了減弱頻繁的大面積重繪引發的性能問題,不同框架不一定需要虛擬DOM,關鍵看框架是否頻繁會引發大面積的DOM操作。

虛擬DOM優化實戰

如果我有1000條數據,我修改了其中兩條,真實的DOM會重新渲染1000條數據,只要發生了變化,就會重新渲染全部數據,虛擬dom 會生成1000個對象 (它是不會被瀏覽器圖形化渲染的),虛擬dom 裏的東西會和真實dom綁定在一起,當數據發生變化 虛擬dom和之前的虛擬dom 會去做數據的比較,當數據發生變化時,纔會去更新數據發生改變的那部分真實的dom元素

但是數組沒有默認的標識,所以數組每次改變都要重新排序,性能影響較大,所以在實時偵聽遍歷數組數據時,需要引入key屬性,用來標識數組數據,一般使用下標標識

<template>
  <div>
      <ul><!--遍歷數組時,添加 key 屬性是爲了優化vnode-->
        <li 
          v-for="(item,index) in list"
          :key="index" 
          @click="list.push('laowang')"
          >
          {{item}}
        </li>
      </ul>
  </div>
</template>
 
<script>
export default {
  mounted() {
    console.log(this);
  },
  data() {
    return {
      list: ["zhangsan", "lisi"]
    };
  }
};
</script>
 
<style>
</style>

下面我們談一下DOM的key值,大家應該也在小程序,vue中遇到過for循環時,如果不給循環的標籤一個key值,瀏覽器會console一個警告,那麼這個key值究竟有什麼用呢,以及爲什麼不建議用index做key值呢?

keys

左圖描述了一個數組,我們在渲染的時候讓數組中的5個數據生成了5個虛擬DOM樹,這時我們新增加一個數據,由於我們沒有給節點key值,所以當我們在做兩個虛擬DOM比對時,節點與節點之間的關係就很難被確立,這點會損耗比對過程的性能。

所以建議大家一定要在循環中給節點加上key值,爲什麼不推薦用index做key值呢,原因在於兩個虛擬DOM比對時,如果key值是固定的(如對象本身,如果是從數據庫讀取的數據,key值可以設置成這條數據的id),這時比對的效率會非常高。

假設使用index做key值,那麼我們在刪除一項數據的時候,會導致index值錯位,如:

原始數據: A-0, B-1, C-2
這時我們刪除A,數據變爲:B-0, C-1

這樣key值就失去了存在的意義,所以官方建議我們使用一個穩定的值去做key值。

以上爲本期介紹的虛擬DOM優化實戰,您可以關注我的公衆號,關注更多前端知識,還有前端大羣一起交流學習!

進階大前端IT圈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章