摘要:本文作者为天猫前端负责人徐凯(花名鬼道),天猫前端是国内最早接触 React Native 并将其用于实践的团队之一,本系列文章中他们将分享使用 React Native 的经验和遇到的问题。本文为第一篇,介绍 React Native 的技术背景、规划和风险。
Facebook 在 3.26 F8 大会上开源了 React Native ,本文是对 React Native 的技术背景、规划和风险的概述。
组里的同学于 4.2 完成了天猫 iPad 客户端“猜你喜欢”业务的 React Native 改造(4 月中发版)。本周开始陆续放出性能 / 体验、稳定性、扩展性、开发效率等评估结果。
图 1 - 4.2 已完成 React Native 改造的业务
背景
为什么需要 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 年发布稿时,发现这么一段:
图 4 - 摘自 React 发布稿(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 所做的改造:
图 5 - 业务和技术改造
自下而上:
- 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 也给出了较详细的描述,可以相互参照。
评论