7

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

 3 years ago
source link: https://zhuanlan.zhihu.com/p/340356521
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

前端玩票,高产玩具,fre,fard,berial,ep……

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

基本:better diff

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

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

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 的注释中提到了,说是因为链表没有反向指针,实现不了这个算法

https://github.com/facebook/react/blob/50393dc3a0c59cfefd349d31992256efd6f8c261/packages/react-reconciler/src/ReactChildFiber.new.js#L765

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

https://github.com/reactjs/rfcs/pull/147

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

无论如何,探索更 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√⭐⭐⭐⭐1kbreact17√⭐⭐41kbvue3×⭐⭐⭐⭐⭐30kbpreactX×⭐⭐⭐⭐4kb

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

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

测试

总结

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

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

最后放一下 fre 的 GitHub 地址吧

yisar/fre

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK