00关系理解
这个是我对RN
和原生关系的理解。简单解释下这个图。
RN js
编写完业务代码后,通过react-native bundle
命令,将代码分别编译成一个index.ios.bundle
和index.android.bundle
文件,当然还是资源文件。然后放到Android
、iOS
的原生工程里,通过黄色说明块里的示例代码,将js
写的所有逻辑业务读成一个View
来展示在原生里,当然这个View
需要Activity/Fragment/ViewController
来承载。然后原生App
打开相应承载的页面就可以看到RN
写的业务了。所以,正常情况下,对于原生来说,所有的RN
页面都是在一个原生页面里的。
顶部还有有个node_modules
,它其实在工程里是一个文件夹,里面存放了所有的js
,Android
,iOS
都需要的一个共同类库以及源码,所有的通信、组件都在这个里面。所以,三个工程里都需要读这个文件夹里的东西,但是我们不用关心具体,这个是由npm
来自动下载的。只需要安装文档提示配置好这个文件夹的路径就ok了。
01性能问题
这里,我的理解是,性能一定不如纯原生写的。
关于RN写出来的应用的性能问题其实一直都是所有开发人员所关心的问题。RN
一直说的是全都是调用的是原生的控件,所以理论上和原生写的App
是不存在性能差异的。
原生封装的控件,在RN
这边以组件的方式来使用。我有一篇文章以WebView
为例讲述了一下原生控件和RN组件的关系(React Native Android从源码看WebView 没有OverrideUrl解决办法,以及高度自适应)。用RN调用的所有组件的属性参数都是经过了js
到java/objective-c/swift
的转换后,才最终渲染成原生封装的控件。而控件在运行中的事件回调也是经过了语言通信,才将信息回调给js。我对语言通信这一块的性能耗时不太了解,但是应该可以肯定的是,本来直接就可以完成的事情,经过了语言转换,肯定是有损耗的。只是Facebook
把这个性能做了很大的优化,再加上现在手机硬件的性能越来越强大,所以,在大部分手机上这个损耗可以忽略。
02我认为的缺点
能做的事情不如原生灵活。我前面说过,
RN
用的组件虽然是原生控件,但是是经过原生封装过的控件,有一定的局限性。为了做到跨平台,他并没有把原生该控件的所有属性参数回调都暴露给js端。坑会比原生开发更多。原生开发,特别是
Android
有很多适配问题要考虑,这些大部分都是经验才能解决的坑,facebook
开发人员在封装控件的时候如果没遇到过相关的坑,可能会解决的不彻底,而js
那边如果不了解原生的话,可能不能完全明白问题出在哪了。所以,原生会遇到的坑,如果facebook
没解决,理论上RN
都会遇到。技术栈会要求更高。这个是肯定的,最好是
Android/iOS
都要有点了解,这样写出来的应用才会更健壮。设计js
与原生通信的方案通用性才会更强。问题的排查也会更准确。
03我理解的优点
最后我才来说优点,是因为虽然有前面的确定,但这个技术本身肯定是值得学习和发扬的。
js与原生的通信机制比较完善。注意我说的是比较完善,实际编码过程中还是有很多不如意的地方。但是满足绝大部分业务需求是没问题的。
可以支持自定义原生控件给RN用。前面我说到,原生封装的控件如果不能满足你的业务需求,你可以自己封装控件,并选择性的暴露接口给
RN
用,当然这个适用于较为复杂的业务需求,如果大部分都控件都需要重新封装,还不如直接就原生写了。支持热更新。这无疑是比较重要的一个优点了,开始我就提到,对于原生了来说,重要的是
js
编译的bundle
文件,而热更新的方案也就可以从这点入手。将bundle
文件和资源文件打成包,当成一个普通的文件下载,然后让原生指定读取路径就可以了。当然这个需要原生支持。跨平台。这也是一个非常重要的有点了。但是打包
iOS
,还是需要必须的硬件配置,比如mac
电脑。可以让更多的前端开发人员来写App。
04
至此!
感谢阅读!