尤雨溪爲什麼要推出 Vapor Mode?

Vapor Mode是尤雨溪在 2022 Year In Review 給定相中提出的概念,本篇文章我們將直觀感受下尤雨溪爲啥要推出Vapor Mode

💎前情提要

React由於架構機制決定了每當狀態發生改變,從當前組件開始一直到葉子組件重新加載。

Vue由於給每個組件建立了watchEffect監聽機制,每當組件依賴的狀態發生改變,當前組件重新加載。

SolidJSSvelte由於在編譯之後就確定了當狀態發生改變UI隨之變化的關係,所以僅僅是具體DOM的重新加載。

根據這些不同的更新粗細粒度,他們被分爲

D6eZn5

💎直觀感受

爲了直觀感受更新時的區別,現在我們設計如下關係的組件:

    GrandFather
      |   
    Father
      |
    Child

每個組件的背景色都是隨機的,並且在Father組件中,實現了一個Count功能。

我們用四個框架分別實現。下面只給出一個例子。

生成隨機顏色:

`#${(~~(Math.random()*(1<<24))).toString(16)}`

Father組件如下:

// Father.jsx
import React, { useState } from 'react'

const Father = () ={

  const [count, setCount] = useState(0)

  const onClick = () => setCount(count => count ++)

  return (
    <div style={{ display: "flex" }}>
      <div
        onClick={() => onClick()}
        style={{
          height: 100,
          width: `40vw`,
          background: `#${(~~(Math.random() * (1 << 24))).toString(16)}`,
        }}
      >
        {count}
        <Child />
      </div>
      <div
        onClick={() => onClick()}
        style={{
          height: 100,
          width: `40vw`,
          background: `#${(~~(Math.random() * (1 << 24))).toString(16)}`,
        }}
      ></div>
    </div>
  )
}

export default Father

接下來,我們看看他們在觸發onClick時的不同表現吧。

🚀 React

🚀 Vue

🚀 Svelte

🚀 SolidJS

🚀 結論

上面的圖中,可以直觀的看到:

React在當前組件狀態發生變化時,從當前組件開始,包括子組件都被重新加載了。

Vue僅僅是當前組件重新加載。

SolidJSSvelte僅僅是重新加載組件!

💎總結

在項目比較小時,SolidJSSvelte的優勢不會很明顯,

但是當面對大型項目時,ReactVue的性能短板就顯露出來了。

面對這樣的壓力,尤雨溪在年初的展望裏已經預告了Vapor mode,該模式的靈感就是受到了SolidJS的啓發。

它可以在給定相同的Vue SFC前提下,與當前基於虛擬DOM的輸出相比,Vapor Mode將其編譯成性能更高、使用更少內存且需要更少運行時支持代碼的JavaScript輸出。

對於React由於架構機制的限制,目前很難做出根本性的改變,

對於開發者,我們可以選擇手動優化。例如,將組件使用memo包裹起來。

const Child = memo(() => <Comp>your comp</Comp>)

此時上面的例子中,React的效果更新效果就和Vue類似了。

我們爲了演示每次dom都是重新加載的,所以樣式是直接這樣寫的。

background: `#${(~~(Math.random() * (1 << 24))).toString(16)}`

在實際開發中,要儘量避免無意義的重複計算,尤其React中,比如:

// bad
<Comp
  style={
    margin: window.screen.width / 3 * 2
  }
/>
// good
const App = () ={
  const margin = useMemo(() => window.screen.width / 3 * 2, [])
  return <Comp style={ margin } />
}

// bettter
const margin = window.screen.width / 3 * 2

const App = () ={
  return <Comp style={ margin } />
}
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/QrBOF6pJ1GxVAnbPmYn0xA