1、響應系統的變動
由原來的Object.defineProperty 的getter 和 setter,改變成為了ES2015 Proxy 作為其觀察機制。
Proxy的優勢:消除了以前存在的警告,使速度加倍,並節省了一半的內存開銷。
2、虛擬DOM重寫(Virtual DOM Rewrite)
虛擬 DOM 從頭開始重寫,我們可以期待更多的編譯時提示來減少運行時開銷。重寫將包括更有效的代碼來創建虛擬節點。

3、組件渲染的優化(優化插槽生成)
Vue2當中在父組件渲染同時,子組件也會渲染。 Vue3就可以單獨渲染父組件、子組件。

4、靜態樹提升(Static Tree Hoisting)
使用靜態樹提升,這意味着 Vue 3 的編譯器將能夠檢測到什么是靜態組件,然后將其提升,從而降低了渲染成本。它將能夠跳過未整個樹結構打補丁的過程。

5、靜態屬性提升(Static Props Hoisting)
此外,我們可以期待靜態屬性提升,其中 Vue 3 將跳過不會改變節點的打補丁過程。

總體來說:1. 更快 2. 更小 3. 更容易維護 4. 更加友好 5. 更容易使用
vdom
1. 性能瓶頸
新vdom生成:
當數據更新時,雖然vue可以定位到最小更新粒度為組件級別,但在組件級別內,還是需要重新遍歷模板生成新的vdom
,更新粒度不夠小。
diff算法:diff
的工作量和組件模板大小成正相關。即使模板內只有少量的動態節點,也需要遍歷整個組件去執行diff
。
總結:vdom
的更新粒度不夠靈活,導致生成新的vnode
和新舊vnode diff
過程中,做了很多無用功,導致浪費性能.
2. 原因
vdom
是從react
而來的,jsx
和手寫的render function
是完全動態的,過度的靈活性導致無法收集優化的信息,即你無法解讀js
的代碼,來區分靜態節點和動態節點。
如下圖,很難識別出:只有div
下的第二個p
是動態節點。

3. 解決方案
react
時間分片
在動態節點和數據的量都很大時,那么在數據更新時,js
線程就會用很長的時間來執行vdom
的相關計算,如果超過了16ms,造成交互或動畫等等卡頓現象。而時間分片就是把vdom
的大量計算分成多個小任務,保證每個小任務在16ms內執行完,從而不會阻塞用戶交互,避免卡頓現象。
即react
承認vdom
的這些缺點,然后它從其他的層面來彌補缺點帶來的問題。
vue
縮小更新粒度
最大化利用的模板信息,把更新的粒度從組件縮小到代碼塊。
即從組件模板中提取出動態節點、動態代碼塊,做diff
時,只需要比較這些動態區域,而忽略掉靜態節點,從而提升性能。




再比如一個節點僅僅
class
屬性為動態的,那么只需要
diff
這一個屬性即可。進一步提升了性能。
總結:vdom
的更新性能將與動態內容的數量相關,而不是模板整體大小。
function-based API

優勢1:更好的支持TS類型推導
優勢2:Tree-shaking友好
常用的API value
、computed
、watch
等都是從vue
中使用import
引進來的,所以支持tree-shaking
。即如果沒有使用這些api,那么這些相應的代碼就不會被打包,縮小了文件大小。
優勢3:代碼更容易被壓縮
對象屬性一般是不會被壓縮的,而變量名是可以被壓縮的
優勢4:邏輯復用
邏輯復用有很多種方案,都有一些缺點:
1. mixins
- 命名空間沖突(多個mixins,不能保證變量名不會沖突)
- 數據來源不清晰(多個mixins時,使用的變量就不易分辨它的來源)
2. 高階組件
- props命名空間沖突
- props數據來源不清晰
- 額外的組件實例性能消耗
3. 作用域插槽
- 額外的組件實例性能消耗
而在vue3中邏輯復用會有不同的方式:

可以發現和
react hook
邏輯封裝形式很像,就是在組件內定義響應式的變量,並封裝變量更改的邏輯,在最后把變量暴露出來,供其他組件使用。
