« 主页

React Native 评估总结

版权声明:眯眼探云原创,可随意转载,请保留该版权声明及链接:https://tyun.fun/post/06.react-native-evaluation/

React Native 是 Facebook 推出的一个跨平台开发移动应用的新技术,主要目的是把 React 的开发体验带到移动平台,并达成跨平台的目标。

本文的核心目标是对 React Native 进行一个全面的评估,考察在项目中试用该技术是否有益。因此,文中充满了总结性的描述,而缺少细节,信息量相当的大。

所以本文的主要潜在读者为:有一定经验的开发者或者技术经理。

React Native的诞生过程

Web技术一直在发展,新技术层出不穷,Facebook作为一个以技术为主导的国际大公司,开源了自己相应的技术,也就是React。很多年前,大家都觉得浏览器是未来,但谁也没想到,iPhone的出现让移动APP成为了未来(现在)的客户端技术。但是网页技术从来没有停止过渗透客户端,除了浏览器以外,还有各种各样的尝试,把H5和JS跑在移动端,希望能打败Native App。但由于性能以及用户体验的问题,这些尝试基本都失败了,只有少部分尝试部分成功了,以 Native + H5 模块的方式,比如微信,比如淘宝。Facebook也在做自己的尝试,他们也尝试了各种方式,希望能统一客户端(Web,iOS,Android)的开发技术,他们还写了这么一篇 博客 来介绍 React Native 的诞生。React Native 最初是从 iOS 客户端开始的,然后发展到了 Android 客户端。并且它仍然处于一个高速发展的阶段。

网页技术的三大核心技术是:Javascript,CSS,HTML5。考虑了客户端的实际情况,React Native 替换了其中两项技术:

网页技术 React Native 对应技术 说明
Javascript Javascript 使用了 JavascriptCore 引擎来运行Javascript
CSS React Native Style:以Javascript对象来表示的一种样式,可以认为是CSS的 一个子集 React Native 自己来解析这些样式,并可以针对跨平台(iOS/Android)作相应的处理
HTML5 JSX:以XML的方式来表示Javascript UI Component 实际使用的时候,有点类似于 H5+PHP 脚本混合的方式

所以,大概可以推断出

  • React Native 是基于 React 的思想来做的,而官方的教程也假设读者写过 React Application
  • React Native 框架在构建上最初是针对iOS,因此程序的结构及思想更接近于 iOS APP
  • React Native 框架和 Native 可以比较紧密的结合

也能推断出一些主要的技术:

  • Javascript,作为核心语言
  • JSX,作为UI的描述语言
  • React Native Style,以及 FlexBox 布局方式
  • React 程序结构,比如Flux(推荐结合Redux)
  • React Native 框架及其组件
  • Native 技术(iOS/Android)

React Native有什么优势呢?

优势 说明
动态发布更新 React Native会把js代码打包成JSBUNDLE,客户端只要重新下载这个jsbundle然后重新加载就可以实现更新。就像网页刷新一样。(注:苹果的条款是这种更新的。)
JS是动态语言 虽然有不少缺陷,但也非常的灵活和强大。而且自从去年发布了ECMAScript6,已经真正成为一门严肃的编程语言了。而且有Babel这种神奇的工具的存在,我们可以随时使用最新的,最屌的 JS 特性。
跨平台 理论上来说,JS代码在iOS和安卓平台上的重用率可以是很高的。各个平台上独有的问题也可以单独处理。
可以以模块的方式集成到APP中 这可以给我们带来两大好处。一、我们可以在APP的某个模块来进行尝试。二、任何 React Native 处理不方便的问题,我们完全可以放在 Native 代码去处理
方便的Web请求 毕竟Javascript,你懂的
方便的数据处理 现在网络一般都用 JSON数据格式,这不就是Javascript的数据格式吗
有中文文档 reactnative.cn,虽然不是最新的,但也还是非常不错的。而且最新的文档其实是有些问题的,最新的文档是从 master 分支上搞出来的,而不是最新发布的分支,所以文档上面有些东西有点超前……
IDE支持 WebStorm IDE可以对 React Native提供不错(但不够完美)的支持

看看Gant Laborde(Tech Lead at Infinite Red)的 评价

  • 跨平台
  • 快速快发
  • 快速上手
  • 优秀的APP结构探路者(不同于常见的MVC),Flux,Redux
  • 想怎么写就怎么写,Javascript就是这么任性(当然,坏处是:别人想怎么写就怎么写)

再来说一下不够NICE的地方

风险或劣势 说明
仍在发展中 React Native技术虽然在快速的发展中(我做评估的这段时间,已经从0.17升到0.21了),但还是有很多不够成熟的地方
没有现成的人才 大约有几个原因:技术本身比较新,技术在快速的发展中,技术背景要求复杂(Web技术本来就是一大堆)
大量的学习成本 不论是对于谁来说(安卓/iOS/前端/后端),想要掌握这门技术,都需要大量的学习。所以最好的情况应该是:需要相对经验丰富的程序员来搭建整体的结构和环境,并把握一些细节。
JS运行时的效率问题 虽然现在已经非常快了,但相比Native,还是有些差距。如果有些关键点出现影响用户体验的的情况,需要专门的做优化
未知的风险 对于一项在快速发展中的新技术来说,肯定会存在各种各样的未知风险。不过有Facebook这样的技术公司背书,这样的风险应该是可以接受的。

同样看看Gant Laborde(Tech Lead at Infinite Red)的评价

  • 合并分支的时候,缓存经常会出问题
  • 升级(React Native)的问题:有时候很快,有时候很坑
  • 导航的问题:很烂,不过Facebook正在做新的解决方案
  • 真机调试的问题:经常都要设置host ip

一些更细节的东西

细节知识点 说明
JS运行环境 JavaScriptCore,也就是webkit的js引擎
UI的渲染 Javascript UI对象被翻译为了 Native 对象进行渲染,因此可以做到非常的流畅
和Native进行交互 通过bridge的方式,可以和原生的控件/API进行交互
UI布局 采用的是 web 上面的 FlexBox 的布局方式
图片的处理 图片的异步加载是非常方便的,解码是放在后台线程(根据依赖来看,图片处理用的是 Facebook 自家的 Fresco 库),所以可以做到很流程。但是目前不能处理大图片,很可能会引起 OOM
按钮的效果 TouchableHightLight,使用起来略有延迟感。后来发现是设置的 touch delay 的原因。也就是说,从技术上来讲,是没有延迟的。
页面的导航 类似于iOS的导航思想。但目前做的还不够好,他们还在改进。
ListView的试用 创建了一个简单的listview,有图片和文字。安卓可以使用下拉刷新控件,iOS也有相应的刷新的控件
如何调试 可以直接在界面上打开界面调试,有点类似于 web 中UI元素的调试,非常的方便。JS调试:可以在上机上打开调试,然后连到 chrome 作为调试服务器。调试的时候运行非常慢
与现有APP的集成 尝试了和安卓APP的集成,还是比较方便的:ReactInstanceManager:一般是和Activity结合来管理 JS 代码运行的生命周期。如果有多个地方(ACTIVITY/FRAGMENT)用到它,推荐的用法是单例模式。ReactRootView:作为rootview来现实,理论上可以嵌入任何位置。不知道多个实例会不会需要特殊的处理。
在React Native中启动本地界面 可以通过 deep link 的方式。也就是说,如果必要的话,可能需要定义一套简单的协议并进行解析,比如:sdylink://api/loadjs。或者也可以通过 bridge 暴露本地接口的方式。
首次页面加载的时候比较慢 可以考虑进行优化,或者加一些动画过度
NODE/Chrome REPL(Read Eval Print Loop) 在学习新语言的时候这是一个炒鸡有用的东东,Python,Swift,Mysql……在Swift里面,这叫做 PlayGround。Node提供了一个Javascript的 REPL 环境,可以帮助我们快速的学习 Javascript
在评估的时候,主要是以安卓为基础的,不过iOS应该也差不了多少。

项目目录结构

典型的 React Native 项目主目录下面包含了4个部分:

  • Android 项目
  • iOS 项目
  • React Native 项目
  • 其他
  • package.json: npm 配置文件
  • npm-debug.log: npm 日志文件
  • .watchmanconfig: watchman的配置文件。watchman用于实时监控日志
  • .flowconfig: Flow的配置文件。Flow是JS的静态类型检查工具
  • .gitignore: gitignore文件

但在实际的项目中,并不一定要这样来组织项目,甚至可以把 React Native 项目和 Android/iOS 项目分开来。因为 React Native 项目最终的目标是生成 JS BUNDLE。而在 iOS/Android 项目中主要是指定 JS BUNDLE 的使用,以及一些 bridge 相关的东西。

JS BUNDLE 服务器

React Native 在开发的时候,提供了一个 Nodejs 服务器用于更新 JS BUNDLE,但是在生产环境中并没有一个完整的解决方案。最基本的方式是把 js bundle 打包到项目里面一起发出去。目前有几种对 js bundle 进行热更新的方案:

  • Reploy:React Native的团队在做一个叫 Reploy 的东西来做这件事,但是我在 Signup 的时候就报错了,看来离能用还有段距离。
  • AppHub:一个第三方的React Native APP的部署,但只支持 iOS
  • MicroSoft CodePush:React Native App的部署服务,免费,支持 iOS/Android。如果实测在国内访问没有问题的话,应该就用它了。 http://microsoft.github.io/code-push/ 虽然说 MicroSoft CodePush 这项服务看起来很不错,也有人推荐,但是我们情况和他们可能会有点不一样,因为我们在中国。这项服务在中国用起来怎么样,还非常值得考察。好在,CodePush是开源的 https://github.com/Microsoft/code-push ,所以理论上来说,如果他们的服务不好用,我们可以构建自己的服务。

小结

总体来说,React Native 还是非常值的尝试的哦~