Description
Facebook在3.26 F8大会上开源了React Native,本文是对React Native的技术背景、规划和风险的概述。看得比较仓促,问题处请直接回复。
组里的同学于4.2完成了天猫iPad客户端“猜你喜欢”业务的React Native改造(4月中发版)。本周开始陆续放出性能/体验、稳定性、扩展性、开发效率等评估结果。
背景
为什么需要 React Native
What we really want is the _user experience_ of the _native mobile_ platforms, combined with the _developer experience_ we have when building with _React_ on the web.
摘自3.26 React Native的发布稿,加粗的关键字传达了React Native的设计理念:_既拥有Native的用户体验、又保留React的开发效率_。这个理念似乎迎合了业界普片存在的痛点,开源不到1周github star破万,目前是11000+。
图1 - React Native github
React Native项目成员Tom Occhino发表的React Native: Bringing modern web techniques to mobile(墙外)详细描述了React Native的设计理念。Occhino认为尽管Native开发成本更高,但现阶段Native仍然是必须的,因为Web的用户体验仍无法超越Native:
- Native的原生控件有更好的体验;
- Native有更好的手势识别;
- Native有更合适的线程模型,尽管Web Worker可以解决一部分问题,但如图像解码、文本渲染仍无法多线程渲染,这影响了Web的流畅性。
Occhino没提到的还有Native能实现更丰富细腻的动画效果,归根结底是现阶段Native具有更好的人机交互体验。笔者认为这些例子是有说服力的,也是React Native出现的直接原因。
图2 - Occhino在F8分享了React Native(Keynote)
“Learn once, write anywhere”
“Learn once, write anywhere”同样出自Occhino的文章。因为不同Native平台上的用户体验是不同的,React Native不强求一份原生代码支持多个平台,所以不提“Write once, run anywhere”(Java),提出了“Learn once, write anywhere”。
图3 - “Learn once, write anywhere”
这张图是笔者根据理解画的一张示意图,自下而上依次是:
- React:不同平台上编写基于React的代码,“Learn once, write anywhere”。
- Virtual DOM:相对Browser环境下的DOM(文档对象模型)而言,Virtual DOM是DOM在内存中的一种轻量级表达方式(原话是lightweight representation of the document),可以通过不同的渲染引擎生成不同平台下的UI,JS和Native之间通过Bridge通信。
- Web/iOS/Android:已实现了Web和iOS平台,Android平台预计将于2015年10月实现。
前文多处提到的React是Facebook 2013年开源的Web开发框架,笔者在翻阅其2013年发布稿时,发现这么一段:
- 加亮文字显示2013年已经在开发React Native的原型,现在也算是厚积薄发了。
- 最近另一个比较火的项目是Flipboard React Canvas(详见 @rank),渲染层使用了Web Canvas来提升交互流畅性,这和上图第一个尝试类似。
React本身也是个庞大的话题不再展开,详见React wiki。
笔者认为“Write once, run anywhere”对提升效率仍然是必要的,并且和“Learn once, write anywhere”也没有冲突,我们内部正在改造已有的组件库和HybridAPI,让其适配(补齐)React Native的组件,从而写一份代码可以运行在iOS和Web上,待成熟后开源出来。
持续更新
规划
下图展示了业务和技术为React Native所做的改造:
自下而上:
- React Node:React支持服务端渲染,通常用于首屏服务端渲染;典型场景是多页列表,首屏服务端渲染翻页客户端渲染,避免首次请求页面时发起2次http请求。
- React Native基础环境:
- Framework集成:尽管React Native放出了Integration with Existing App文档,集成到现有复杂App中仍然会遇到很多细节问题,比如集成到天猫iPad客户端就花了组里iOS同学2天的时间。
- Networking改造:主要是重新建立session,而session通常存放于http header cookie中,React Native提供的网络IO fetch和XMLHttpRequest不支持改写cookie。所以要不在保证安全的条件下实现fetch的扩展,要么由native负责网络IO(已有session机制)再通过HybridAPI由JS调用,暂时选择了后者。
- 缓存/打包方案:只要有资源从服务器端加载就避免不了这个话题,React Native也是如此,缓存用于解决资源二次访问时的加载性能,打包解决的是资源首次访问时的加载性能。
- MUI是一套组件库,目前会采用向React Native组件补齐的思路进行改造。
- HybridAPI是阿里一组Hybrid API,此前也在多个公开场合分享过不再累述,React Native建立了自己的通信机制(@bang),看起来更高效(未验证),改造成本不大。
- 最快的一个业务将于4月中上线,通过最初几个业务改造推动整体系统的改造,如果效果如预期则会启动更大规模的业务改造。
更多详细规划和进展,以及性能、稳定性、扩展性的数据随后放出。
风险
- 尽管Facebook有3款App(Groups、Ads Manager、F8)使用了React Native,随着React Native大规模应用,Appstore的政策是否有变不得而知,我们只能往前走一步。
- React Native Android 预计2015年10月才发布,这对希望三端(Web/iOS/Android)架构一致的用户而言也算个风险。
- iOS6 JavascriptCore为私有API,如在iOS6上使用有拒审风险。
- ListView 性能问题需要持续关注(react-native github issue)
React Native相对于Webview和Native的优势和劣势 @berg 也给出了较详细的描述,可以相互参照。
持续更新...
鬼道
2015.4.6