fre 更新了,框架設計重思考……

132發表於2019-04-21

halo 大家好,好久不賤呢~

好久沒出來浪了::>_<::,主要是之前在重構 c站,現在重構完了

是時候重構一下俺的輪子了……

所以,如你所見,smox、fre、eplayer 都更新了

這篇文章,主要來說說,fre 框架的設計

Use

import { h, render, useState } from 'fre'

function Counter() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

render(<Counter />, document.getElementById('root'))
複製程式碼

這段程式碼大家應該很熟悉啦,react hooks API 就是個奇蹟

而我,看到這種正常思維根本想不出怎樣實現的 API 天生有種痴迷

本質

react hooks API 為什麼難以實現,其實本質是 this 的缺失

如果這是 vue,我們可以通過依賴收集的時候,知道是哪個元件,然而 react 並沒有

事實上,react 的 hooks 是存在於 fiber 的

原理

唉,一不小心又說到 fiber 了,好尷尬

fiber 網上的文章蠻多的,大多寫的都雲裡霧裡,對於 hooks 而言,其實關鍵在於 連結串列的遍歷

連表的遍歷和遞迴遍歷不一樣的是,連結串列能夠一條鏈走完所有的節點

而遞迴的兄弟節點是斷連的

什麼意思,就是說,fiber 能夠使得我們走一遍,能夠順序的拿到所有的 function 節點,然後,有個全域性變數在更替,這個就是我們要的 this 了

設計哲學

唔,上面說了一點點 hooks 內容,好像跑題了……

重點還是框架設計哈!其實框架,是個人喜好的不同搭配,僅此而已

尺寸 元件化 狀態更新
fre 1kb hooks Fiber
preact 3kb class diff
vue 10kb SFC Proxy + diff
react 33kb class + hooks Fiber

以上,先看個表格,我馬上,要開始編作文了

元件化

對於一個框架來說,元件化是很重要的,比如 react 主要是 class 的方案,vue 是模板引擎和單檔案,fre 是 function ……

首先,我是很不喜歡 vue 的 模板引擎的,這是真的

但是它也有好處,比如自帶 runtime,比如能夠自己控制編譯,更方便的編譯到小程式,甚至我看到滴滴的 cml 框架直接用標籤搞了個多型協議(編譯時走指定標記內容)

但是談到設計,我還是將它歸類為無可救藥的元件化機制

然後就是 react 的 class 方案,瀏覽器支援,但也有缺點——

class 其實很難在 1kb 的框架裡搞定,主要是 class 有生命週期事件,還有 context 這種重頭,而且 class 的擴充形式比較絕望,HOC、render props、extend 等

然後就是 hooks API,它的優點就是複用方便,function 一把鎖,而且 API 很魔幻 缺點就比較致命,不能拿到 this 導致很多事情都做不了,也沒有多餘的字元,搞編譯也不可能

要知道,國內的框架,到頭來都去搞多端編譯了都……

狀態更新

框架的另一個要素,狀態更新機制,看圖

fre 更新了,框架設計重思考……

經過投票,可以看到,最終剩下的,就 react 和 vue3 的方案

而我個人,超級喜歡騷的 API,所以自然是選擇了 proxy

當然 fre 是 fiber 了,所以其實不是我最喜歡的,但是也沒辦法,我第一個版本是使用 Proxy 搞的,後來發現,還是和 react 保持一致的好……好抄

但是我確實最喜歡 Proxy 無疑,稍等我再說

vdom diff

單獨將 diff 拿出來說::>_<:: 其實我們看到很多框架是沒有 diff 的,如 vue1.x,然後就是遞迴的 diff,如 preact、vue2.x

還有就是 react 的 fiber

其實呢,對於 vue 而言,確實 diff 的必要性不是很大,但是同樣的,對於 react 而言,fiber 的必要性也不大(⊙o⊙)…

所以,對於成熟的框架,這種機制只是一種必需品,用來高度抽象的,統一非瀏覽器環境的

所以如果寫一個框架,我覺得還是一定要加一層 vdom 的

優先順序排程

不得不提一下 react 的優先順序的排程,通俗來說,就是它能擺脫瀏覽器的堆疊,高優先順序任務一定執行,低優先順序任務抽空執行

這個排程方案的實現,要麼依賴 fiber,要麼依賴 runtime

所以其實 react 和 vue 都可以做

但是我不喜歡 vue 的 runtime ,fiber 也一時半刻搞不定

唉,所以 fre 內部目前還是 micro task

總結

綜上所述,fre 的各個方案,綜合起來看,其實只是擁有了一個完成度還算 ok 的 1kb

hooks API 固然騷,也奈何沒辦法多端編譯,後續發展是個問題

而 vue 的模板我又很不喜歡,我還想搞排程,所以……如果我想寫一個理想的框架,大概長這樣:

  1. Proxy 的狀態更新方案,騷
  2. class 的元件化方案,綜合考慮最好的元件化方案
  3. 使用 web-component 作為 runtime,搞排程
  4. 擁有 vdom diff,使用 JSX

以上,是我對新框架的思考,我先不搞了,你們來呀!

最終,放上 fre 的 github 地址:

github.com/132yse/fre

歡迎 star 與 pr ::>_<::

相關文章