Faster than faster——RN新架构中的JavaScript Interface

背景

随着Flutter等新框架的崛起,React Native正经受着愈来愈大的挑战,RN性能上的瓶颈愈发明显。为了在与Flutter等框架的对抗中保持竞争力,RN酝酿在架构上进行了一次很是大的升级。因而,在一篇ReactConf 2018的演讲 React Native's New Architecture 中,RN官方向咱们引出了三个新的概念:JSI,Fabric和TurboModule。随后在2019年第一季度,RN开发人员@kelset 写了一篇从高层设计上解释RN为什么如此架构的文章: formidable.com/blog/2019/j…。下面就让咱们来看一看RN是怎么解决性能瓶颈问题的。node

现有的问题

RN老的架构很是重的依赖于Bridge:git

RN-bridge

全部的JS和Native之间传递的信息,都要序列化为JSON以后进行异步传输。这样就形成一个比较常见的性能问题:快速滑动ListView的时候会白屏,以下图:github

ListView白屏

如今有三个线程:Native的UI线程,Layout线程和JS线程,他们之间的通讯是异步的。当ListView向上滑动,须要展现新的Cell的时候,Native异步通知到JS线程,JS线程作相应的业务逻辑处理以后,先是异步给到Layout线程,计算Cell的实际显示区域,以后Layout线程再将算好的结果异步给到Native线程进行UI绘制,因为滑动很快,这样就形成UI得不到及时的更新,显示成白屏。浏览器

要解决这个问题,咱们看一看在浏览器里,ListView是怎么作到没有白屏的问题的。服务器

浏览器ListView

浏览器返回的node里,是有指向C++实际生成的对象的引用的,因此说,JS向浏览器里的调用是同步调用,天然就不会有白屏的问题。网络

一样的思路,咱们若是去掉这个异步的bridge,JS和Native同时持有一个HostObject,那样就能够进行JS和Native之间的同步调用了,这里就引伸出了bridge的替代者——JavaScript Interface (JSI)。架构

JavaScript Interface (JSI)

JSI是一个精简通用型的JS引擎接口,理论上能够对接任何JS引擎,包括Google的V8和微软的ChakraCore,或者是RN如今使用的JavaScriptCore(JSC)的新版本(JSI已经集成到RN的0.59版本中,而且在该版本中升级了JSC的版本)。框架

同时,JSI是架起 JS 和Native之间的桥梁,经过在C++层实现一个 JSI::HostObject,如今不须要序列化成JSON并双向传递等一系列操做,实现了Native和 JS间的直接通信。异步

JSI

JSI下的ListView滑动

JSI ListView滑动

虚线是异步调用,实现是同步调用。性能

首先咱们RunApplication,以后异步render,而后再异步到UI线程更新View。在JSI出现以前,这是咱们Native和JS交互的惟一处理方式。

如今UI线程有一个网络请求更新state的回调,紧接着在UI线程有一个列表的onScroll事件,显然,这个onScroll事件是咱们急需处理的任务。有了JSI,咱们就能够同步的处理这个onScroll的任务,更新相应的Native View,就不会有白屏的问题出现。处理完这个紧急的任务,主线程能够继续处理网络请求回调的任务了。

JSI下的Native Modules

JSI同时是Native Modules重构(即TurboModules)的基石。好比如今有一个需求,在RN中拍照并向服务器上传图片。在JSI出现以前,咱们须要在JS和Native之间,反复序列化来传递数据,低效且毫无必要:

Native Modules call old

在有了JSI以后,JS和Native同时持有一个HostObject,获取到图片以后,舍去了没必要要的数据传递,直接继续完成上传的操做。

Native Modules call new

Reference

React Native's New Architecture

formidable.com/blog/2019/j…

相关文章
相关标签/搜索