fre2 发布,更好的 Concurrent 前端框架

2,461 阅读4分钟

halo 大家嚎,好久不贱呀!终于!!我在 2020 年最后一天!搞完了一个夙愿 —— fre2!

看到标题有没有想要打死我的节奏??哈哈哈不要着急,容我细细道来

基本:better diff

fre1 的 diff 算法抄的 react,一直饱受诟病,因为着实不是个好算法,fre2 这次最大的变化就是带来了新的算法

fre2 的算法主要使用了双端遍历,这样就有了处理公共前后缀的机会

1 2 3 4
1 3 2 4

1 和 4 相同,直接跳过,直接变成了中间元素的对比

  2 3
  3 2

vue,inferno 等框架,都使用了这种预处理,据说这一个小小的预处理,可以获得很大的性能提升

在算法实现上,主要是使用了两端循环,这样可以保证 O(n) 复杂度的前提下,节约代码量

newStart = 0
newEnd = newChildren.length
oldStart = 0
oldEnd = oldChildren.length

while(newStart <= newEnd && oldStart <= oldEnd) {
  if(same(newChildren[newStart], oldChildren[oldStart]) {
    // update
    newStart++; oldStart++
  }
  else if(same(newChildren[newEnd], oldChildren[oldEnd]) {
    // update
    newEnd--; oldEnd--
  }
}

if(oldStart > oldEnd) {
  while(newStart <= newEnd)
    // insert
}
else if(newSart > newEnd) {
  while(oldStart<= oldEnd)
    // remove
}
else {
  ...
}

这个算法在 react 的注释中提到了,说是因为链表没有反向指针,实现不了这个算法

github.com/facebook/re…

fre 的解法是在链表生成的过程中做这个算法,而不是遍历链表,显然 react 团队当初没有想到

新的 diff 算法对 fre 而言意义重大

过去的我就是个怂货,当别人问 fre 和 react 有何不同的时候,我无语凝噎

现在我终于可以昂首挺胸:fre 的算法比 react 好

我终于可以宣布:fre 站起来了!

未来:Fiber,tearing,compile

算法是框架的基础,除了基础算法,fre2 的大方向和 react 还是近似的

tearing

众所周知,fre1 是一个 1kb 的 react-like 框架,它除了有和 react 一样的 API 之外,还拥有了一样的 concurrent mode,比如 time slicing

我更喜欢将其称为 Fiber,因为 Fiber 是一种协程的实现,而优先级调度属于多线程

这种模式最大的问题就是 tearing,这也是为什么 concurrent mode 一直无法正式进入生产的原因

如图,其实很容易理解,就是一个组件的渲染是可以中断的,此时如果依赖一个“外部状态”,比如 redux,mobx 等

然后这个状态在渲染过程中发生变化,那么将会导致这个组件,接下来渲染的内容为新状态,之前的内容为旧状态

这种撕裂随处可见,几乎大部分第三方库都会出问题

解决 tearing 问题是 fre2 地主要任务,目前有一个解决方案就是 uMS

github.com/reactjs/rfc…

本质上就是给外部状态一个“版本号”,发现版本不一致,这个组件就需要重新渲染,但这不是最好的方案,因为这样会导致重复渲染

无论如何,探索更 safety 和 efficiently 的异步渲染,将会是 fre2 的主要方向

compile

最近 react 发布了一个新 feature:server component

说实话,一打眼看上去真的不咋地,一言不合就开车,开的是历史倒车

但其实我更加关注的是这种 AOT 的优化,以及 中间码 带来的可能性,fre2 也会做这方面的尝试

但这部分内容不会内置在 fre 中,很可能是一个额外的库,做额外的事

比如我现在可以想到的是,在 server 端将中间码渲染成字符串,就可以得到一个更好的 ssr,没有 runtime,不需要二次水合

fre2 可能会做基于 server component 的 ssr

QA

  1. fre vs react vs vue?
框架concurrentdiff 算法尺寸
fre2⭐⭐⭐⭐1kb
react17⭐⭐39kb
vue3×⭐⭐⭐⭐⭐30kb
preactX×⭐⭐⭐⭐4kb

如上,每个框架各有千秋,自行判断吧,其实这些基准都无关紧要,这四个框架都不慢

重点是,比如你想要什么,你想要找份工,很可能 vue 和 react 适合你,你想要探索 concurrent 的实现,可以考虑看 fre

  1. 测试覆盖率

目前已经跑通 fre1 所有的测试,fre1 的测试已经很全了,但从 issue 来看,还有没有覆盖到的 case,需要补全

总结

其他方面,比如 devtool 和时间旅行,这些都可以在 fre2 中玩一下

2020 年,和 fre1 说再见,新的 fre,新的算法,新的方向,新的征程……

最后放一下 fre 的 GitHub 地址吧

github.com/yisar/fre

大家对 Fiber,concurrent mode,时间切片,异步渲染 这些关键词感兴趣的话,除了看 react 源码,不妨也来看看 fre

希望新的一年里,可以遇到更多小伙伴,我们一起来创造!

另外,fre 开启 discussion 了,欢迎随便发言~