因为在公司里一直维护小程序,然后由于我重构了编译器,所以小程序会进入一段维护期,不会再大改了
这段时间我在寻找新坑,我们公司有个坑一直没人做,也就是动态 flutter,支持热更新,支持预加载,支持分布式开发
社区内的方案
框架 | 架构 | 优点 | 缺点 |
---|---|---|---|
mxflutter | 使用和 flutter 一致的 js api,构建和 flutter 一致的 widgets tree | 成本最小,心智负担最低 | 必须和 wdigets tree 完全对应,语法上存在限制 |
flugy | 使用 widgets 模拟 dom | 成本适中 | 成本较高,不能完美模拟 |
kraken | 直接在 render object 层模拟 dom | 抽象比较好 | 成本最高,大力出奇迹 |
以上,是目前市面上最主流的三种方案,除了 mxflutter,其他两种方案都去模拟 dom
说实话我不是很喜欢模拟 dom 的思路,尤其是在 dart 这样一个语言中,runtime 太重总归不是好事
我一直认为,好的架构,它的心智模型一定是足够简单的
所以如果是我,我更喜欢 wxflutter 的思路,但 wxflutter 的语法确实存在限制,如果我们有办法用 jsx 生成一颗静态树就好了?
能不能做到呢?
答案是:当然能。
静态 jsx
flutter 的 widget 是完全静态的,所以我们使用 jsx 模拟是非常简单的
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter Demo"),
),
body: Center(
child: Text('Hello Flutter'),
),
);
}
}
用 jsx 描述,就是
<Scaffold>
<AppBar title="Flutter Demo" />
<Center><Text>Hello flutter</Text></Center>
</Scaffold>
静态 jsx 很容易做到,但是问题来了……
如果走默认的 jsx 编译器,则只能编译出下面的结果:
{
Scaffold: fn(),
}
只有执行这个 fn 才能获得接下来的子树,这可不行,所以现在的难题变成了,怎么编译 react 组件为静态对象
react 组件静态化
假设我们一个 react 组件,长这样:
function App(props){
const [count, setCount] = useState(0)
let a = 0;
return <Scaffold>
<AppBar title="Flutter Demo" />
<Center><Text onPress={() => setCount(count+1)}>{count}{a}{props.b}</Text></Center>
</Scaffold>
}
我们编译器使用一种反向编译的技术,从 return 的 jsx 中分析变量来源
则这段 jsx 中有三种类型的变量
from hook:count, setCount
from props:b
form self:a
那么编译结果就很简单了:
[
['count', 'setCount'],
['b'],
['a'],
['Scaffold',{'onPress': 2},['AppBar'...]]
]
经过这一波操作,整个 react 应用不再有动态的东西,它没有可执行的组件,也没有动态的语法,它会得到一棵高度优化的静态树
我们将这棵树传递到 dart 端,调整一下就可以变成 widgets tree 了
线程通信成本
无论如何,这还是一棵树,传递它如果走 json 的序列化和反序列化,性能肯定很差
解决方案其实很简单,想办法绕过 js,dart 直接和 js 引擎通信即可
但这块我还没有做,所以未必能找到方法,如果找不到,则只能退而求其次,走二进制的序列化
总结
我们没有选择在 runtime 模拟 dom 的方案,也没有使用 js 生成 widget 的方案,而是选择 react 编译生成 widget 的方案
框架 | 方案 | 优点 | 缺点 |
---|---|---|---|
rotter | 将 react 编译为 widget | 心智负担小,react 标准 | 仍然存在限制,但可以通过编译器进行 lint |
这里的重点工作在于对 react 组件的编译,将其编译为一棵静态树
当然,这样做也有缺点,就是我们不得不将 react 组件作为完全静态的字符串去对待,所以限制也存在
但我坚信只要编译器设计地足够好,虽然无法覆盖 100% 地场景,但可以提供完善地编译器检查,和 lint
原文 https://zhuanlan.zhihu.com/p/397681827
今天给大家介绍传统扫雷游戏的制作思路吧,为什么选择这个游戏呢?1.它太金典了,金典到我们都知道,都玩过,都会玩;2.它也是一个轻量级的小游戏,比较简单。
像是生活中的任何事情一样,只有通过汗水和时间,才能精通于编程。编程技巧与其他技巧没有什么不同,投入 10000 小时之后,你也可以成为程序界的大佬
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!