背景

目前社区中的使用 native 编写的打包构建工具(esbuild、swc)在性能上明显比 babel 等传统使用 js 编写的工具强大不少

Parcel 2 beta 3

babel 毕竟他的 transformer 插件生态是基于 js 来写的,所以 native 短时间内取代 babel,不过可以看出使用类似 Rust、Golang、C++ 的静态编译语言来写前端构建领域的一些底层能力是一个大的趋势。

但是这种路线的可能会因为插件社区活跃程度(因为前端同学大部分还是 only js 起手)导致其发展受到干扰,除非你让那些 js 脚本小子去写 C++,可是大部分同学学个 TS 都有很大的学习迁移成本,所以需要一个折中的办法来平衡性能 / 社区活跃程度。

JSI

React Native 的老架构是 native 层和 js 层通信的过程是一个完全异步的过程,这个过程的性能损耗堪比网络请求,每一次通信都需要序列化和反序列化。

之后新架构给出的答案是 jsi:一个能让 js 层拿到 native 层提供的 host value 或者 host fucntion(基于线程共享内存),毕竟已经是基于内存进行操作了,所以所有的通信过程全部都是同步的。

而且其使用起来也非常简单,比如我们使用 jsi 在 native 定义一个 test 函数

void LoveUbinding::install(jsi::Runtime &runtime,
                          std::shared_ptr<LoveUbinding> loveUbinding) {
  auto moduleName = "nativeLove";
  auto object = jsi::Object::createFromHostObject(runtime, loveUbinding);

  runtime.global()
         .setProperty(runtime, moduleName, std::move(object));
}

绑定一个函数

jsi::Value LoveUbinding::get(jsi::Runtime &runtime, 
                            const jsi::PropNameID &name) {
 
 auto methodName = name.utf8(runtime);
 auto &test = *test_;
 
 if (methodName == "nativeLove") {
   return jsi::Function::createFromHostFunction(runtime, name, 0,   
     [&test](jsi::Runtime &runtime, 
             const jsi::Value &thisValue, 
             const jsi::Value *arguments, size_t count) -> jsi::Value { 
       return test.loveU();
     });
 }
 
 return jsi::Value::undefined();
}

然后将其定义为一个原生的模块(TurboModules,让其主动发现该模块时才会进行调用)

这个绑定过程先不写了,因为这个过程的逻辑完全可以复用,没什么好说的,直接只写一套就好了。

最后在 js 层直接 run 下面的代码。

global.nativeLove.loveU()