8

写个新框架,名叫asta

 3 years ago
source link: https://zhuanlan.zhihu.com/p/359367111
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.

写个新框架,名叫asta

俺,只想跪在床上娇喘,不想隔着网线叫唤

会不会被打死!哈哈哈哈哈

这次的起因是群友在讨论 vue3 和 svelte,牵扯出了很多历史,俺就姑且谈一下,求轻打

历史

一切都得从 angularjs 说起,当时基于脏检查的双向图存在性能问题,然后才有 vue 和 angular2

其中 vue 使用了 Object.defineproperty 实现了细粒度的更新,性能得到了提升

然后因为 react 的兴起,vdom 大热,这时候的框架们都开始引入 vdom,也就是后来的 vue2

再之后,vdom 的劣势逐渐显现出来,angular8 实现了 ivy,使用 idom,svelte 也出现了

然后 vue3 为了兼容旧版本,保留了 vdom——的同时,开始在语法糖层面趋近于 svelte

以上,差不多就是这样,angular,vue,svelte 三个框架彼此杂交

svelte

svelte 其实整个实现不难,我之前写过一个 1kb 的版本,后来整个 html parser 用到了 wean 中

ctripcorp/wean

不得不说,svelte 的语法糖真的让人眼前一亮,非常简洁

但是这种实现,太没意思了,就是一个 compiler,没有复杂的数据结构和算法

而且在 keyed 的情况下,因为缺乏 runtime 的算法,svelte 的性能很差

angular ivy

讲道理,angular ivy 是很惊艳的,倒不是 tree shaking,而是 idom

idom 可以理解为一种 retained mode 的 vdom,这是 angular ivy 的奥秘

// vdom

h("ul", {},
  todos.map((todo) => h("li", {}, h('text',{},todo)))
)

// idom

open('ul')
todos.forEach(toto => {
  open('li')
  text(toto)
  close('li')
})
close('ul')

看到这个模样,我是有点激动的,因为我知道这是我想要的

vue

讲道理,vue3 一开始的演讲我是很喜欢的,当时说的是 10kb,性能提升一倍

当然还有人调侃说,你干嘛不写 mini vue,答曰:vue3 似乎并不大

谁能想到!谁能想到 vue3 最终形态是 30kb,而且性能也没有提升很多(傻叉基准中和 vue2 接近)

而且说实话,我更喜欢 vue2 的源码,相信有很多人会有同感

fre

好了,问题来了,如果让我写个新框架,我会怎么写呢?

因为我已经写了 fre 了,fre 有一些优点,也有很多缺点

首当其冲的缺点就是 jsx 和 vdom,这俩玩意真的是,成就了 react 也成就了 svelte

react 因为 vdom 而火,svelte 因为没有 vdom 而活

asta

哈哈哈,这是我给新框架取的名字,asta

其实如果只是写个 web 项目,fre 已经足够了,如果只是为了 web 我没必要写个新框架

asta 可以理解为 angular 的迷你版,但长得像 svelte,也可以理解为 vue4(vue的另一个模样)

反正就是 avs 的杂交产物

  1. template

我很喜欢 svelte 的 template 设计,非常简洁好看

但是之所以使用 template 还有其他原因,比如 template 能让我做更多编译优化,而且 template 可以更大程度上限制输入

限制性很重要,它可以一次性阉割大量业务 case

2. idom

idom 作为 vdom 的替代品,可以缓解 vdom 的缺陷,它不仅仅可以节约内存

更重要的是跨平台

idom 的数据结构是在内存里构建的,我们只需要在 js 层调用 rust 的方法

然后 rust 层就可以构建一棵 idom 树了

可以说,idom 是 template 前提下 vdom 的最佳替代品

3. 脏检查

其实响应式更新的实现方式总共有三种,脏检查,Proxy,setState

setState 是粗粒度的,组件级别,所以基本上不考虑它

Proxy 和脏检查几乎是一样的,但 Proxy 有 ref 的致命缺陷

脏检查是 angular1 的机制,因为使用了双向图,导致性能很差

但如果对数据结构进行调整,则整个实现会很赞

https://github.com/yisar/dirty-check

总结

大概就是这样,我准备写一个

  1. 重编译轻 runtime
  2. 增量细粒度

评论真的惨不忍睹,基本上属于看不懂文章的,实际上看完文章就知道,整篇文章我基本上没有提到 vue 的机制,更多的是 angular

同一个模样,每个人选择完全不同的机制,有人选择 vdom,有人选择 idom

之所以戏称 vue4,是因为 vdom 不适合编译型框架,不要太当真

yisar/asta


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK