阅读 1601

fre2 RFC - 2020 框架设计总结

halo,大家好,我是 132,今天给大家带来一篇框架设计的总结文章

首先庆祝 fre 已经一岁啦,在过去的一年里,star 终于过千了,在 2019开源中国评选 中排名第八

然后就……现在 fre 也完成了接近 100% 的测试覆盖率,已经处于稳定期了

所以总的来说,现在是时候做个总结了,然后顺便预测一下接下来的方向

组件化方案

为什么要将 组件化方案 放到第一个要谈的点,因为今年 react hooks 和 vue composition 的出现,使得前端框架的组件化方案彻底从 class 蜕变为 function

起初,react 的组件化方案是 class

class HelloMessage extends Framework.Component {
  render() {
    return <div>Hello world</div>;
  }
}
复制代码

class 的方案主宰了很多年,直到现在还有一些新框架,如 omi,stencil,angular,在框架最初就选择了 class

它的好处是,主要是这几个方面:

  1. 贴合 web component,符合 web component 默认范式
  2. 方便往 this 上挂东西,比如挂 scoped css
  3. HOC,render props 等都不是很灵活,样板代码更适合做编译多端(如 taro,nanachi)

它的坏处:

  1. 不是很需要 web component
  2. 不是很需要编译跨端(如 fard,kbone,taro-next)
  3. 不是很需要 this,super,extend,组合优于继承

综上所述,class 的优缺点都有,但是对于今年来说,很明显 class 的优点大家已经不在意了,事实上除非你写的是 web component 框架,不然 class 没什么好的

然后,今年的大成就是 function 组件,hooks 和 composition,他们的共同好处是逻辑复用,共同缺点是由于方便了逻辑复用,导致会写出很多面条代码,难维护

我们先说 composition,它长得这样

import { h, ref, reactive } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const object = reactive({ foo: 'bar' })

    return () => <div>
      {count}{object.foo}
    </div>
  }
}
复制代码

我们看到,劫持两个变量,然后返回一个闭包,这样做的好处

  1. 返回闭包,变量不需要每次都初始化
  2. 不需要 memo,deps 等心智负担

坏处是

  1. 需要 ref 和 reactive 两个 API
  2. render function 必须是 plan function
  3. 闭包陷阱

以上,composition API 并不是和 vue 官方文档一样,只有好处没有坏处,以后用于生产,问题会慢慢暴露出来

然后说 react hooks / fre hooks

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

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

如上,直接返回 vdom,而不是显式返回闭包

这么做的坏处:

  1. memo 和 deps 的心智负担
  2. 变量频繁初始化,如果变量是个 heavy value,那么会阻塞组件

这么做的好处是

  1. 有利于 concurrent 和 Suspense
  2. API 好看

综上,其实 hooks 的缺点也不多,说白了就一个——心理负担 但是一旦你熟悉了 deps 的规则,你就会得心应手

以上,是今年关于组件化的总结,总的来说就是,前端框架今年还是 function 为主,彼此都有好处和坏处,大家随便选一个即可

视图更新

这是今天我想说的第二个点,也就是 UI 的更新,这也是我今年下半年做的事情

  1. exact updating vs top-down updating

精确更新和自上而下的更新,精确更新首先是 vue 提出来并给出实现的,它的本质是浅比较 props,来判断是否需要 update

我觉得这个可以接受,但是……fre 团队大部分人都非常排斥这个,他们一致认为 vue 的做法是不可接受的

github.com/yisar/fre/i…

我也很绝望,我现在期望能够找到一个更好的方案,令人普遍接受的方案

但是说实话我很喜欢精确更新,因为这样一来,可以从很大程度上减少 hooks 的重复初始化

  1. 异步更新

目前 vue,preact 等框架的异步更新就是一个简单的微任务,没有其他任何处理

fre 的异步更新是时间切片,它的本质是使用 while 循环链表,然后任务可以在 dom 操作之后的宏任务中执行(相当于空闲时间)

时间切片只是其中一个方法,用于减少 UI 的阻塞,也是目前粒度最小的方法

针对 vue 这种,更新和dom操作无法拆,更新也无法拆的框架,还有另一个方案

github.com/vuejs/vue-n…

我把它叫做双队列更新,原理是排队论,如果你前面排队的人耗时时间太长,那就去旁边等着,先让后边的来,别碍事

综上所述,异步更新无非就两种模式,精确更新和上下更新,更新队列目前最好的两种,fiber架构下的时间切片和普通架构下的双队列排队

其他

除了组件化和试图更新,其他方面,如vdom和template,mutable和immutable,这些今年都没有什么新东西,我就不说了……

最后,来说说 fre2

因为说实话,现在 fre1 已经完全稳定了,而目前 fre 比 react 就缺了 Suspense

所以 fre2 大概是这样:

  1. 改用 typescript
  2. Suspense
  3. useTransition
  4. 重构更新队列

我也需要新的点子,所以招人啊招人,招人一起贡献新点子!

github.com/yisar/fre/i…

issue 大门时刻为你打开!

关注下面的标签,发现更多相似文章
评论