动态

详情 返回 返回

純js、v-for、vue函數式組件、vue普通組件性能對比

先説結論

  • dom 節點數量對內存影響沒想象中大,js 變量才是內存佔用的元兇
  • 內存佔用及運行性能對比:原生 js < v-for div ≈ v-for 函數式組件 < v-for 普通組件
  • 去虛擬 dom 化框架正在崛起,成為一種新的選擇

dom 節點數量對內存影響沒想象中大(十萬 div 僅佔用 400mb)

  • 測試示例
  • 生成 100,000(十萬)個 div,內存佔用僅 400mb,平均每個 div 佔用內存 400 * 1024 kb / 100,000 = 4kb
  • 注意,這裏內存佔用是靜態狀態內存,即 div 生成完成後等待一會(約1min)內存回收完成後的內存佔用,div 生成過程中會產生中間變量,內存佔用會比靜態時高。
  • 如果短時間多少清空 div 再重新生成,會導致內存佔用變大

組件過多,或許才是 vue 項目內存佔用大、運行慢的原因

分別以「純 js 渲染 div」、「v-for 渲染 div」、「v-for 渲染函數式組件」、「v-for 渲染普通組件」為例做性能對比測試

「純 js 渲染 div」運行示例,對應源碼

  • 10,000(一萬)個 div

    • 渲染耗時:26ms,平均單個div渲染耗時:0.0026ms
  • 100,000(十萬)個 div

    • 渲染耗時:265ms,平均單個div渲染耗時:0.0027ms
  • 100,000(十萬)個 div

    • 佔用內存:528mb,平均單個佔用內存:528 * 1024 / 100,000 = 5.4kb

「v-for 渲染 div」運行示例,對應源碼

  • 10,000(一萬)個 div

    • 使用 key 緩存節點渲染耗時:61ms,平均單個div渲染耗時:0.0061ms
    • 不使用 key 緩存節點渲染耗時:91ms,平均單個div渲染耗時:0.0091ms
  • 100,000(十萬)個 div

    • 使用 key 緩存節點渲染耗時:499ms,平均單個div渲染耗時:0.005ms
    • 不使用 key 緩存節點渲染耗時:286ms,平均單個div渲染耗時:0.0029ms
  • 100,000(十萬)個 div

    • 佔用內存:586mb,平均單個佔用內存:586 * 1024 / 100,000 = 6kb

「v-for 渲染函數式組件」運行示例,對應源碼

  • 10,000(一萬)個 div

    • 使用 key 緩存節點渲染耗時:85ms,平均單個div渲染耗時:0.0085ms
    • 不使用 key 緩存節點渲染耗時:82ms,平均單個div渲染耗時:0.0082ms
  • 100,000(十萬)個 div

    • 使用 key 緩存節點渲染耗時:392ms,平均單個div渲染耗時:0.0039ms
    • 不使用 key 緩存節點渲染耗時:505ms,平均單個div渲染耗時:0.005ms
  • 100,000(十萬)個 div

    • 佔用內存:654mb,平均單個佔用內存:654 * 1024 / 100,000 = 6.7kb

「v-for 渲染普通組件」運行示例,對應源碼

  • 10,000(一萬)個 div

    • 使用 key 緩存節點渲染耗時:122ms,平均單個div渲染耗時:0.0122ms
    • 不使用 key 緩存節點渲染耗時:360ms,平均單個div渲染耗時:0.0325ms
  • 100,000(十萬)個 div

    • 使用 key 緩存節點渲染耗時:918ms,平均單個div渲染耗時:0.0092ms
    • 不使用 key 緩存節點渲染耗時:13881ms(13.8s),平均單個div渲染耗時:0.1388ms
  • 100,000(十萬)個 div

    • 佔用內存:907mb,平均單個佔用內存:907 * 1024 / 100,000 = 9.3kb

通過上述測試可得

純 js 渲染 v-for 渲染 div v-for 渲染函數式組件 v-for 渲染普通組件
一萬div複用key渲染耗時 - 61ms/6.1us 85ms/8.5us 122ms/12.2us
一萬div不復用key渲染耗時 26ms/2.6us 91ms/9.1us 82ms/8.2us 360ms/36us
十萬div複用key渲染耗時 - 286ms/2.9us 392ms/3.9ms 918ms/9.2us
十萬div不復用key渲染耗時 265ms/2.7us 499m/5us 505ms/5us 13881ms/138.8us
十萬div內存佔用 528mb/5.4kb 586mb/6kb 652mb/6.7kb 907mb/9.3kb
  • dom 節點數量對內存影響沒想象中大,10萬 div 佔用內存 400mb(只生成一次),平均單個 div 佔用內存僅 4kb
  • vue 組件對內存佔用較大,僅僅最簡單的 div 組件就需要額外添加 9.3 - 5.4 = 3.9kb 內存,若組件複雜度上升,則內存佔用將進一步增加。成為內存瓶頸
  • vue 函數式組件、v-for div 是否使用 key 緩存節點,對運行耗時變化不大
  • vue 組件是 key 緩存節點,對節點更新性能有很大提升,10萬組件更新,從 13s 耗時優化到 0.9s 耗時,減少近 13 - 0.9 / 13 = 93% 運算耗時
  • vue 組件並非越細越好,顆粒度太細,將導致 vue 組件數量急劇增加,內存佔用急劇增加
  • 純 js 渲染 div 最快,使用 v-for div,v-for 函數式組件的渲染耗時至少是 純 js 渲染耗時的兩倍,這是由於虛擬節點 vnode 需要執行 diff 算法決定的。

去虛擬化正在崛起

既然 vnode 計算如此消耗性能,那可否捨棄 vnode 來提高性能呢?答案是肯定的,svelte(類似 vue),solid(類似 react) 就是這麼做的
Svelte,新興前端框架 Svelte 從入門到原理,Virtual DOM is pure overhead,虛擬DOM是純粹的浪費

Solidjs,SolidJS入門


對於 Svelte,尤雨溪​怎麼看

user avatar
0 用户, 点赞了这篇动态!

发布 评论

Some HTML is okay.