上一篇文章,我们应该已经对跨平台有了一定的概念,但这里其实有一个问题并没有解决,就是其实在ios和安卓
上的样式是有差异的,那么我们的Rn
就需要去抹平这种差异化,rn
中采用的是css-in-js
,使用Flexbox
,能确保在不同屏幕下一致的布局。
我们在js
中写的style
对象,在native
中将由单独的一个线程去处理,就官网叫做影子线程(Shadow thread)。在这个线程中由Yoga
引擎(这也是facebook开发的)重新去计算app
的布局,这个引擎在计算了有关app
界面的东西后,将结果又反馈至native
线程,最终呈现出来。
那么一个完整的老版本的架构是这样的:
大伙现在应该已经对一个rn
的整体架构有了基本的了解,还记得上篇文章的问题吗?桥
的负载会导致性能问题,那么新的架构就是为了去解决这个问题。
关于新架构的内容很多,可能有些地方我自己也有理解不当的地方欢迎指正。
我们先讲讲最大的改动,就rn
在新架构中直接把老的桥干掉了,直接换成了一个新的中间层或者说通用层
,也就是 JS Interface (JSI)
。在这个通用层里面有很多的新内容我们可以先看一下这个架构图,有个概念再往下看。
So,我们来看看有哪些变化,上面的图中间部分,就是JSI
。(解释一下为啥这个图是这样的,因为就Turbo Modules
我其实认为是Native Moudles
的加强,而Fabric
是Renderer
的加强)。
1、JS-bundle
不在强依赖
于JavaScriptCore
(后续都用jsc简称了)引擎了。我们现在可以很方便用更好的引擎去替换了,性能更好了。比如Hermes
。
2、JSI
让我们可以直接在js
层调用native
的方法了。JSI
是c++/oc
写的,JSI
中间层直接存储了native
层的引用和属性(就是把native
层的东西绑定到了全局),然后我们js
就可以调用java/oc的api
。
3、Turbo Modules
的出现(上图中的Native Moudles),在之前的架构中 JS
使用的所有 Native Modules
(例如蓝牙、地理位置、文件存储等)都必须在应用程序打开之前进行初始化,这意味着即使用户不需要某些模块,但是它仍然必须在启动时进行初始化。
Turbo Modules
基本上是对这些旧的 Native 模块的增强,正如在前面介绍的那样,现在 JS 将能够持有这些模块的引用,所以 JS
代码可以仅在需要时才加载对应模块,这样可以将显着缩短 RN
应用的启动时间。
4、Fabric
也就是上图中的renderer
,一个新的UI渲染器
,它就相对于在c++中,可以直接创建一个 Shadow Tree
,一个就是快,也减少了渲染特定元素的步骤。
可能大家没懂,举个例子:当 App
运行时,React
会执行你的代码并在 JS
中创建一个 ReactElementTree
,基于这棵树渲染器会在 C++
中创建一个 ReactShadowTree
。Fabric
会使用 Shadow Tree
来计算 U
I 元素的位置,而一旦 Layout
完成,Shadow Tree
就会被转换为由 Native Elements
组成的 HostViewTree
(例如:RN 里的 会变成 Android 中的 ViewGroup 和 iOS 中的 UIView)。
5、 codegen
其实就是一个静态类型检查器,CodeGen
使用类型确定后的 JavaScript
来为Turbo Modules
和 Fabric
定义供他们使用的接口元素,并且它会在编译时生成更多的native
代码,而非运行时。
Ok,上面都是框架的架构设计,我们先有一个大体的概念,那么现在我们稍微走近实战去了解一些必要的模块。
React-native
只内置了一些必要的包为了尽可能的减小包的大小,然后rn
是个可扩展框架,许多的包需要你自己去下就像asyncStorage
这种,这种装包你也需要一点点依赖相关的原生知识,但问题不大,一般都会有模版去教你,照着抄就行了(但也不一定,绝大数情况是)。那么我们现在就看看一些基本上是必要的包
。
用得最多的路由库,用于创建导航菜单还有screens
,成熟解决方案也多。
antd mobile
估计国内我们基本用的都这个或者就是自己封装的原生,推荐几个其他的NativeBase
、React Native Element
、 UI Kittern
、 React-native-paper
其实启动页就是你js
线程启动前展示的过度页面,React-native-bootsplash
。
react-native-vector-icons
、 react-native-svg
。
通常,当我们开发一个web应用时,我们很好处理错误,因为它们不会超出JS
的范围。简单的说我们前端就是web
的王(掌控力),我们可以很容易地看到原因,并在DevTools
中打开日志。
但Rn
因为除了环境的JS之外,我们还有native
组件,这也可能导致app
执行中的错误。因此,当发生错误时,我们的应用程序将关闭立即我们很难弄清楚原因,因此React-native-exception-handler
也正是解决这个问题的包。
其实如果是ios我们要更新应用上传到商店,有这么个技术OAT
可以替换js包,可以看看微软的Codepush
。
rn中文文档地址,就这2篇文章都是在理一些基础概念的东西,一起学习的话可以看这里,有很多志同道合的小伙伴。