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 導致很多事情都做不了,也沒有多餘的字元,搞編譯也不可能
要知道,國內的框架,到頭來都去搞多端編譯了都……
狀態更新
框架的另一個要素,狀態更新機制,看圖
經過投票,可以看到,最終剩下的,就 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 的模板我又很不喜歡,我還想搞排程,所以……如果我想寫一個理想的框架,大概長這樣:
- Proxy 的狀態更新方案,騷
- class 的元件化方案,綜合考慮最好的元件化方案
- 使用 web-component 作為 runtime,搞排程
- 擁有 vdom diff,使用 JSX
以上,是我對新框架的思考,我先不搞了,你們來呀!
最終,放上 fre 的 github 地址:
歡迎 star 與 pr ::>_<::