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 ::>_<::