iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
Modern Web

Vue 演進驗證 × AI Coding 時代的工程實踐系列 第 22

Day 22:Composable 越拆越細,真的只有好處嗎?

  • 分享至 

  • xImage
  •  
從 Component Tree 轉向 Reactive Graph,看看 Composable 擴張後到底增加了什麼成本?

前端開發很常遇到 Code Review 過程中被要求,這段邏輯可以抽出去,之後可能會共用。

於是原本寫在 Component 裡的幾十行程式碼,被整理成:

const search = useUserSearch(users)

過幾天需求增加:

const search = useUserSearch(users)
const pagination = usePagination()
const sorting = useSorting()
const selection = useSelection()

再繼續拆,可能會變成:

useUserPage()
├─ useUserSearch()
├─ usePagination()
├─ useSorting()
├─ useSelection()
└─ useLoading()

從程式碼結構來看,這通常更容易閱讀、測試,也更容易重用,但是 我們抽出去的只有程式碼,還是連 Runtime 要處理的 Reactive Dependency 也一起增加了?

一個 Composable 背後有多少 Reactive 工作?


先看一個很普通的搜尋功能:

function useUserSearch(users) {
  const keyword = ref('')

  const result = computed(() => {
    return users.value.filter(user =>
      user.name.includes(keyword.value)
    )
  })

  watch(keyword, () => {
    trackSearch(keyword.value)
  })

  return { keyword, result }
}

Component 只需要:

const { keyword, result } = useUserSearch(users)

但 Runtime 需要處理的結構已經包含:

Composable 不是一行 function call

因此 Composable 本身不是效能問題,真正值得測量的是:Composable 的組合,最後形成了多少 Reactive Dependency,以及一次 State Change 需要處理多少工作。

Composable 還可以繼續組 Composable


實務上很少只有一層,例如:

function useCounter() {
  const count = ref(0)

  const doubled = computed(() => count.value * 2)

  return { count, doubled }
}

function useCounterView() {
  const counter = useCounter()

  const label = computed(() =>
    `Count: ${counter.doubled.value}`
  )

  return { ...counter, label }
}

function useCounterSummary() {
  const view = useCounterView()

  const summary = computed(() =>
    `${view.label.value}`
  )

  return { summary }
}

呼叫端看起來只有:

const { summary } = useCounterSummary()

但實際上可能形成:

當抽象繼續往下組合,Reactive Graph 可能怎麼擴張?

這就是 WP5 要研究的核心,我們需要把程式碼層級的 Composable 數量,轉換成 Runtime 可以觀察的成本。

Component Storm 和 Composable Explosion,其實是兩種不同的問題


前一個 WP4 的 Component Storm,主要觀察:

Component Tree
      ↓
Render / Update
      ↓
Runtime Cost

例如:

<UserPage>
  <UserTable>
    <UserRow />
    <UserRow />
    <UserRow />
  </UserTable>
</UserPage>

問題是一次 State Change 之後,有多少 Component 需要重新執行 Render / Update?

Composable Explosion 不一樣,它不直接增加 DOM,也不會因為多了一個 useXXX() 就多一個 Component。

它主要增加的是:

Composable Composition
        ↓
Reactive Graph
        ↓
Dependency Propagation
        ↓
Runtime Work

所以這一次我們要看的,是 Reactive Architecture

所以這次要驗證什麼?


Composable 越多,不能直接推論 Runtime Cost 越高。

真正需要看的,是 Composable 背後形成的 Reactive Graph,以及 State Change 發生後需要處理的 Dependency。


上一篇
Day 21:AI 寫出來的 UI,會不會變成新的 Rendering Anti-pattern?
下一篇
Day 23:建立 Composable Scenario
系列文
Vue 演進驗證 × AI Coding 時代的工程實踐23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言