大家好,我是 132,又是周日啦,基本上现在实习后,只有周六日可以写自己的东西了
这周周六主要是去 airbnb 做了一次技术交流,和小哥哥一起讨论了很多 fard 相关的内容
然后周日,就按照讨论的思路进行了重构,发布了新版本
接下来我们捋一捋:
fard block tree
唔,大家如果看到之前的文章的话,会发现 fard 的 bridge 是使用 template 来做的 通过 template 模拟 vdom
但是很不幸,微信不支持 view 标签的递归,这就很尴尬
导致我们要写很多重复代码,不符合我性格
好在最终我研究出了一种新的方式,使用自定义组件来做
这是这次更新最大的变化,得先说,还记得今年 vue3 的 block tree 吗?
如图,其实 vue 的 block tree 本质就是将 diff 的单位从组件缩减到区块,而这个区块和组件的区别,只是前者是类似于 react fragment 的一个数组
vue 的这个思路,说实话不是新鲜事,而且其实对于 web 的 diff 来说,收益不大,因为传统的 web diff 也是有 key 的,而除了遍历,其他的性能开销少得多
但是不得不说,小程序我们没办法控制 ui 层面的 diff,这个 block tree 的思路还是非常好的
所以与之对应的我搞出来适用于小程序的 fard block tree
感受下这个颜值,shdow dom + fard bridge + dom 的逼格……
大家可以看到,这个截图其实和也是有 block 的感觉的,只是本质区别在于,vue 是将一个组件的 vfor 拆成多个 block,而 fard 是将一个组件(页面)的 wxfor 拆成多个组件
最终的目标都是一致的,缩减单位更新的范围
经过这么一折腾,不仅仅解决了 template 的性能天坑,还能收获一波新的性能提升
但是这还没完呢……
data diff
我们一直都知道,setData 要次数少,量小,要先压缩
而 fard 给出的方案,也是微信推荐的……diff
比如
let oldVdom = {
type: 'view',
props: {
class: 'item'
},
children: [
{
type: 'text',
props: {},
children: []
}
]
}
let newVdom = {
type: 'view',
props: {
class: 'wrap'
},
children: [
{
type: 'view',
props: {},
children: []
}
]
}
const out = diff(oldVdom, newVdom)
复制代码
比如我们更新一个 vdom ,一不小心就吧整个对象传过去了 而 fard 会自动做一层 diff,以上这种情况,其实只是变化了两个字段:
{
"props.class": "wrap",
"children[0].type": "view"
}
复制代码
这是 fard 第二个性能大提升的方面
但是……还没完 emmmm
我们解决了 setData 的量的问题,还没解决次数问题
防抖
其实 fard 只会 setData 一次,但是也有一些情况是不那么稳妥的,所以需要做 防抖 处理,保证每次都发生一次 setData
new Promise((resolve, reject) => {
if (!Object.keys(diffRes).length) {
resolve(null)
return
}
context.setData(diffRes, () => {
resolve(diffRes)
})
})
复制代码
经过 promise 的小优化,能保证只进行一次,而且会检查有没有变化,没有就直接 return
很好,将 setData 的次数也优化好了
然而,还没完::>_<::
以上我们解决的是,第二次以后的,更新阶段的,但是首次渲染的 data 的量仍然是个坑
json 的压缩
我们想到的是压缩对象,比如:
{
type: 'view',
props: {
class: 'item'
},
children: [
{
type: 'text',
props: {},
children: []
}
]
}
复制代码
然后变成了:
{
t: 'view',
ps: {
class: 'item'
},
c: [
{
t: 'text',
p: {},
c: []
}
]
}
复制代码
大量简写一些不对外暴露的字段……此处应该还有别的办法,如果你知道,求告知
以上,是 fard 对于小程序性能优化做的探讨
fard
fard 是我写的 fre 转小程序框架,它不需要编译,类似 RN 的原理,是真真正正的在小程序里跑 fre
加上各种性能优化骚操作,使其成为异常精彩的设计
从此再也不用 cli,再也不用受限制,只要能跑 js ,就可以跑 fard!
最后放上 fard 的 github 地址:github.com/132yse/fard
欢迎 star 与试用,也可以加群哦~