下一代 React Native 会是什么样的?— Recos

咱们团队很早就接入了 React Native,其动态化下发面对咱们这个三天两头改界面的团队是挺契合的。虽然 Flutter 大火,但咱们如今并无去尝试,一个是动态化对于咱们过重要了, 另一个是咱们跨平台选择了“业务逻辑使用KMM, 音视频用 C++,界面用RN”的路子,能够知足团队的需求,还有一个缘由是,如今即便是跨平台技术了,业务太多,客户端的人也太少了,已经被困在业务里走不动了,心有点累。前端

可是 RN 被诟病的主要仍是性能太差,一堆不知缘由的 Native Crash。咱们不能由于它存在问题,那就换另外一套技术,而是要去优化它,解决它的问题,这也是咱们技术走向深度的一个路子。git

随着时代的发展,Native UI 已经有了新的产物, Android 这边诞生了 Compose, iOS 诞生了 SwiftUI, 都是采用声明式的语法,能够说 React 开创了 UI 的新时代, Native 已经有新的产物,那么 React Native 是否也应该与时俱进?不过 React Native 官方团队的开发节奏有点慢啊,一年前提出了 JSI 去解决通讯问题,而后就一直卡在 TurboModule 里走不出来了。 因此去年我就有一个想法,我只去用 React, 从新用 Compose 实现一个 React Native,彻底采用 JSI 与 TurboModule 的形式, 由于没有历史包袱,也只去支持 Hermes 引擎,并且只去支持咱们用到组件,理论上会简单不少, 业余时间,我也的确去这么作了,也初步作出了 Demo, 事件流程、基础组件、Flex 布局等都实现出来,看似有点搞头,可是在长列表上,个人想法是 js 渲染出全部的 virtual dom, 而后到了 Compose 端, 将它们做为数据传递给 LazyColumn 进行渲染, 可实现发现,js 去建立成千上万个 virtual dom 时依旧很耗时, 这个路子走不通,想了一些其它的路子,可是须要去魔改下 React,不想这么作,最终好像又要回到 React Native 社区提供的 RecyclerListView 的形式, 有点不爽。github

不过想着想着,又有了新的思路, React 是声明式的语法, SwiftUICompose 也是生命式的语法,那么咱们可不能够把它从 React 的写法翻译到 ComposeSwiftUI 上呢。 基于静态代码翻译,确定可行, 可是咱们想要的是动态下发,那该怎么搞呢?在与同事的讨论中,我想到了一个方案: 一个语言,在编译前端的呈现是什么呢? 是 AST 结构,那么咱们是否是能够序列化这个 AST,而后在 Compse 环境去解释执行这个 AST 呢? 那咱们就来试一下。babel

JS 的 AST 须要咱们本身去解析文件生成吗? 不,前端有强大的 babel,因此咱们能轻松拿到 js 的 ast 结构, 咱们能够适当的简化下,渠道多余的信息,减少生成文件的大小, 由于流程就变成这样子了:markdown

design.jpeg

想法有了,那就去作作看,新建个项目, 命名为: Recos闭包

Github 地址:github.com/cgspine/Rec…app

目前 Compose 的 Demo 已经写出来了,开篇就是一个长列表, 能够无任何依赖的执行下面代码:框架

function Item1(item, onItemClick){
    const onClick = useCallback(() => {
        onItemClick(item)
    })

    return <Text style={{ color:'#fff' }} onClick={ onClick }>偶数:{item.name}, {item.count}</Text>

}

function Item2(item, onItemClick){
    const onClick = useCallback(() => {
        onItemClick(item)
    })

    return <Text style={{ color:'#fff' }} onClick={ onClick }>奇数:{item.name}, {item.count}</Text>
}

function HelloWorld(current){

    const [data, setData] = useState([])

    useEffect(() => {
        let ret = []
        for(let i = 0; i < 1000; i++){
            ret.push({
                name: 'item' + i,
                index: i,
                count: 0
            })
        }
        setData(ret)
    }, [current])

    let render = function (i) {
        let item = data[i]
        if(item.index % 2 == 0){
            return Item1(item, (it) => {
                it.count = it.count + 1
                setData(data)
            })
        }else{
            return Item2(item, (it) => {
                it.count = it.count + 2
                setData(data)
            })
        }
    }

    return <RecyclerView count = { data.length } render = { render }>Hello World!</RecyclerView>
}
复制代码

React 里的 useState, useCallback, useEffect 我都去实现了下,感受努努力,就能够用到生产环境了。dom

若是去实现下 React Native 的全部接口, 那就能够与之相兼容了。ide

目前看来,这个就彻底两个方面的能力:

  1. 编译原理的前端知识,咱们要去写 js 解析器了, 如今我写的这些代码,只是能工做,效率什么都须要逐步优化,还有不少语法解析没支持到。
  2. 考察 js 的基本功,什么做用域、闭包、变量提高,对象、原型链, 都须要从根本去搞懂它。

一些想法的产生、落地都须要不少基本功的落地,而不是只会调用某些框架就能搞定的,继续努力吧, 有兴趣的而且承认这个思路的同窗,能够参与到这个项目来,努努力,让咱们再次重铸JS昔日辉煌,干掉 ReactNative,干掉 Flutter。

相关文章
相关标签/搜索