前端早早聊大会,前端成长的新起点,与掘金联合举办。 加微信 codingdreamer 进大会专属周边群,赢在新的起跑线。
第二十六届|前端互动专场,了解互动编程|互动性能|互动美术|地图世界等等的可能性,5-15 下午直播,5 位讲师(蚂蚁/淘宝/字节等等),点我上车? (报名地址):

所有往期都有全程录播,可以购买年票一次性解锁全部
正文如下
本文是第十七届 – 前端早早聊框架专场,也是早早聊第 121 场,来自自由职业 – 132 的分享

自我介绍
哈喽,大家好!俺是 132,前面有几位讲师讲了很多领域,包括跨端,web GL 游戏引擎,还有微前端,就差小程序了,小程序这套架构还是恨套路的,让我们一起探讨一下下

先做一下自我介绍,我是伊撒尔,简称 132,写过很多框架和轮子,比如 fre,berial,eplayer 等,大家平时有什么想问我的,可以去 fre 仓库的 disscussions 中随便发,俺都是不介意的

我们的小程序框架的底层,我把它分为四个部分,主要是
- 多线程模型
- runtime 框架
- js 沙箱
- 其他
我们一个一个来
多线程模型和线程通信

多线程模型
![图片[1]-132-打造一个轻量的小程序引擎玩玩-一一网](https://www.proyy.com/skycj/data/images/2021-05-14/151475a5a569db9c08ca491d1272cbc5.jpg)
多线程模型是一个非常常见的 UI 模型,包括 RN、flutter 统统都是使用的这个模型,小程序也不例外
它们其实只是线程主体的不同,比如 RN 主要是 shadow tree 和 jscore,而 flutter 则是 skia 和 dart engine,小程序则是 webview 充当渲染层,js engine(或 worker)充当逻辑层
尽管本质一样,但因为业务场景的不同,小程序的诉求却和 RN/flutter 完全不同
在 RN 中,app 作为一个主体,我们更乐意分配更多资源,以至于 RN 一直在跑 react 这种 runtime 浪费的框架,在过去,这被认为是值得的
但是小程序与之相反,它作为 app 的附属品,我们不乐意给小程序分配更多资源,不乐意分配内存,不乐意分配更多线程,所以我们这次分享的前提是
基于最小分配的前提,探讨小程序的每个环节
请记住前提,然后我们接着往下看
线程通信

说到多线程,我们首先想到的就是多线程的调度和通信,我们先讲通信,通常来说,多线程的非 UI 线程都是没有 dom 环境的,无论是 js 引擎还是 worker
所以为了能跑一个前端框架,我们不得另寻出路,主要方案有三种,其中幻灯片的第二种,写一个 dom 无关的 diff 算法,这是写不出来什么好算法的,所以我们主要看剩下两种思路
![图片[2]-132-打造一个轻量的小程序引擎玩玩-一一网](https://www.proyy.com/skycj/data/images/2021-05-14/06d86015319d33ddfa981637201a4f2d.jpg)
幻灯片中,左边的代码是 [ 使用 Proxy 劫持 dom ],右边的是 [ 模拟 dom API ]
这两种思路其实是类似的,模拟 dom API 是最为常见的,比如 react-reconciler,vue3 的 renderer,都是用的这个思路,就是它把用到的 dom API 暴露出来,你在不同的端去模拟 dom 的行为
甚至还有 taro-next,kbone 这种框架,他们模拟了一整个 dom/bom 层
这个思路好处是粗暴方便好用,坏处就是抽象程度低,比如 taro-next 中就用了千行代码做这件事,属于 case by case,没啥逼格
所以我提出了 Proxy 劫持 dom 的思路,其实这个思路在微前端中比较常用,只不过我们现在用 Proxy 不再是劫持一两个 dom 操作了,而是将所有 dom 操作通通记录下来,然后批量发送给 UI 线程
这个实现抽象程度非常高,我使用了不到 200 行代码就可以劫持所有 dom 操作
代码在这里:github.com/yisar/fard/…
除了线程通信,更重要的是线程的调度,因为很重要,我们放到最后说
前端框架
![图片[3]-132-打造一个轻量的小程序引擎玩玩-一一网](https://www.proyy.com/skycj/data/images/2021-05-14/b696977fa1261b2fac8f39116fd51a63.jpg)
还记得小程序架构的前提吗?没错,就是最小资源分配
因为我们不想给小程序分配过多的资源,所以像 react、vue 这种 runtime 特别重的框架,其实是不适合用作小程序的
甚至 fre 也不适合,因为大家可能对“轻量”这个词有误解,不是代码越少就越轻量,代码量是很重要的一个方面,但是更重要的是代码的内存占用,以及算法的算力和复杂度
fre 虽然代码量少,但它的算法和 vue 是一样的,算力相同,内存占用也不少

所以我们不得不将目光转向 svelte 这类框架,幻灯片可以看到,svelte 通过编译,直接生成原生 dom 操作,没有多余的算法和 vdom
实际上,我们在做性能优化的时候,讲究一个“换”字,react 这种框架,通过浪费 runtime 去做算法,“换”一个最小结果,而 svelte 则是通过编译(浪费用户电脑),去换 runtime
JS 沙箱
![图片[4]-132-打造一个轻量的小程序引擎玩玩-一一网](https://www.proyy.com/skycj/data/images/2021-05-14/82d224da600bf4f0cabaf39c4774d80c.jpg)
然后我们来讲讲沙箱,也就是 js 引擎和 worker,这部分适合语言爱好者
选型
![图片[5]-132-打造一个轻量的小程序引擎玩玩-一一网](https://www.proyy.com/skycj/data/images/2021-05-14/3704d1ec0f2fbd5d02fc996207a3e6ef.jpg)
通常来说,一提到 js 引擎,大家都是 v8 v8 v8
但是实际上,v8 是一个高度优化的 JIT 引擎,它跑 js 确实是足够快的,但对于 UI 来说,我们更多要的不是跑得快
![图片[6]-132-打造一个轻量的小程序引擎玩玩-一一网](https://www.proyy.com/skycj/data/images/2021-05-14/7e09dba3b26a303021c7466b3d286b2f.jpg)
实际上,AOT 的语言或引擎更适合 UI 框架,比如 RN 的 hermes,dart 也支持 AOT,它可以编译成字节码,只需要一次构建即可,当然,AOT 也有缺点,就是 热更新 比较难做
另外除了 js 引擎,worker 也是一个非常赞的选择,方便好用,而且还提供了 bom 接口,比如 offscreen canvas,fetch,indexdb,requestAnimationFrame……
总结

哈哈哈总结,我们基于最小分配的前提去设计这个架构,每个环节都选择节省资源的方案
事实上写代码就是这样的,比如我写 fre,那么我追求 1kb,0 依赖,我写业务框架,我追求 0 配置,1mb 的 node_modules 总大小
我写小程序,我追求最小资源分配,不管做啥,有痛点然后有追求然后才有设计
其他

其实小程序还有很多东西可以做,比如现在的小程序都需要兼容微信小程序,也就是类似 wxml,wxss,wxs这些非标准的文件,还要得是个多 Page 的 mpa
比如 ide,我们可以使用 nobundle 的思路来加快构建速度
当然,为了服务业务,在我们公司我没有使用 nobundle

比如剧透一下,我在公司中为了兼容微信小程序,开的新坑
原理是将微信的文件(wxml,wxss,wxs)先编译成可识别的文件(jsx,css,js),然后使用 babel、postCss 去转移,形成一个个 umd 的子应用
然后通过 berial(微前端框架)的路由,沙箱,生命周期,将它们跑在 h5 端,这样就可以在浏览器中模拟和调试啦
最后我们通过三张图和一个问题,来补充和结束一下这次分享
第一张图是微信小程序的后台桌面,有没有感觉和操作系统有点像,但其实不是的,操作系统的软件是进程的关系,只能切换,不能共存,而小程序是多进程,这些小程序可以在后台留驻,随时保持唤醒
第二张图是钉钉的仪表盘,这也是小程序最常用的场景,就是和这种一堆子应用的 app
第三张图是 vscode 的插件系统,是的,想不到吧,这玩意也是小程序架构,而且也是同样的思想,我不让你操作 dom
然后最后的问题:canvas 怎么办?
这个问题实际上非常难搞,如果我们使用 worker 作为 js 沙箱还好,有 offscreen canvas 和 requestAnimationFrame
如果我们使用 js 引擎怎么办呢,走上面提到的线程通信成本就太高了,动画走这个通信,等接收到消息,动画已经卡死了
所以还有什么办法,这里不得不再次提多线程的特性,也就是多线程的内存是共享的,我们可以 js 引擎中,将 canvas 整个元素放到堆栈里,然后 UI 线程和 js 线程共享这一块内存
这样就不需要走线程通信了,适合 canvas,动画这种场景
![图片[7]-132-打造一个轻量的小程序引擎玩玩-一一网](https://www.proyy.com/skycj/data/images/2021-05-14/1a78c7421c5c15b5f90e09b344c6a2d9.jpg)
演讲过程中有点紧张,废话比较多,建议回放 2 倍速,这篇文章是我重写的,精简了很多,希望对大家有所帮助
最后,蟹蟹大家,再贱!
别忘了 5-15 的第二十六届|前端互动专场,了解互动编程|互动性能|互动美术|地图世界等等的可能性,5-15 下午直播,5 位讲师(蚂蚁/淘宝/字节等等),点我上车? (报名地址):

所有往期都有全程录播,可以购买年票一次性解锁全部
别忘了给文章点赞






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)