翻譯自Vuejs issue中尤大的回答:原文地址vue
在Web應用程序中,丟幀(janky)更新一般是因爲同步的高CPU時間和原生DOM的更新形成的。git
時間切片是在CPU工做期間保持應用響應的一種嘗試,但它隻影響CPU工做。DOM的刷新必須是同步的,以確保最終DOM狀態的一致性。github
因此,想象兩種丟幀更新的場景:數組
也就是說,只有在頻繁進行超過100ms的純CPU任務更新時,時間切片才實際有用。緩存
有趣的地方在於,這樣的場景更常常地發生在React中,由於:markdown
React的虛擬DOM操做(reconciliation )天生就比較慢,由於它使用了大量的Fiber架構;架構
React使用JSX來渲染函數相對較於用模板來渲染更加難以優化,模板更易於靜態分析。併發
React Hooks將大部分組件樹級優化(即防止沒必要要的子組件的從新渲染)留給了開發人員,開發人員在大多數狀況下須要顯式地使用useMemo
。並且,無論何時React接收到了children
屬性,它幾乎總要從新渲染,由於每次的子組件都是一棵新的vdom樹。這意味着,一個使用Hook的React應用在默認配置下會過分渲染。更糟糕的是,像useMomo
這類優化不能輕易地自動應用,由於:框架
PureComponent
。不幸的是,大多數開發人員都很懶,不會積極地優化他們的應用。因此大多數使用Hook的React應用會作不少沒必要要的CPU工做。dom
相比之下,Vue就上面的問題作一下比較:
本質上更簡單,所以虛擬DOM操做更快(沒有時間切片-> 沒有fiber
-> 更少的開銷);
經過分析模板進行了大量的AOT優化,減小了虛擬DOM操做的基本開銷。Benchmark顯示,對於一個典型的DOM代碼塊來講,動態與靜態內容的比例大約是1:4,Vue3的原生執行速度甚至比Svelte更快,在CPU上花費的時間不到React的1/10。
智能組件樹級優化經過響應式跟蹤,將插槽編譯成函數(避免子元素重複渲染)和自動緩存內聯句柄(避免內聯函數重複渲染)。除非必要,不然子組件永遠不須要從新渲染。這一切不須要開發人員進行任何手動優化。
這意味着對於同一個更新,React應用可能形成多個組件從新渲染,但在Vue中大部分狀況下只會致使一個組件從新渲染。
默認狀況下, Vue3應用比React應用花費更少的CPU工做時間, 而且CPU工做時間超過100ms的機會大幅度減小了,除非在一些極端的狀況下,DOM可能成爲更主要的瓶頸。
如今,時間切片或併發模式帶來了另外一個問題:由於框架如今安排和協調了全部更新,它在優先級、失效、從新實例化等方面產生了大量額外的複雜性。全部這些邏輯處理都不可能被tree-shaken
,這將致使運行時基線的大小膨脹。即便包含了Suspense
和全部的tree-shaken
,Vue 3的運行時仍然只有當前React + React DOM的1/4大小。
注意,這並非說併發模式是一個很差的主意。它提供一個有趣的新方法解決某一類問題(尤爲是相關協調異步狀態轉換),但時間切片(做爲併發的一個子特性)特別解決了React中比其餘框架更突出的問題,同時也帶來了成本。對於Vue 3來講,這種權衡彷佛是不值得的。