金氧

Rexxar:豆瓣对混合开发的思考

前段时间,豆瓣将自己的混合开发框架Rexxar开源了。豆瓣可以说是在国内对HTML5实践最早的一批公司,早在2013年的时候他们就应用了当时还显得超前的Web Component概念开发了CardKit移动UI框架。在移动开发上,豆瓣也采用了混合开发的模式,Rexxar就是他们实践和思考的结晶。我采访了Rexxar的主要开发者之一郭麟,看看他们对混合开发的思考。

豆瓣使用混合开发的原因,是因为他们需要同时提供iOS、Android、移动Web版本的页面,相对于同时开发三个版本,使用混合开发显然可以在代码重用、开发成本和效率方面有很大的优势,在权衡性能体验的前提下,使用混合开发是非常现实的选择。

Rexxar是什么

Rexxar是一个针对移动端的混合开发框架。支持Android、iOS和移动Web。

Rexxar主要由三部分组成:

Rexxar-web:前端代码库。包括一套打包、调试、发布工具,以及公共前端组件,和对Rexxar Container实现的Widget的调用。

Rexxar-Router:路由表,将每个页面分配一个服务器端链接,以及一个本地URI,通过路由表来访问页面。

Rexxar-container:增强版WebView,封装了一些Native API支持,包括OAuth授权、图片缓存等。

Rexxar目前已经开源,并且分为3个项目,你可以只使用其中某个项目来开发对应平台的代码:

https://github.com/douban/rexxar-web
https://github.com/douban/rexxar-android
https://github.com/douban/rexxar-ios

混合开发的注意点

对于混合开发,很多团队都有过实践,从大家分享的内容来看,重点无非以下几类:

  • 增强WebView:原生WebView基本是PC平台浏览器内核的移植,但对于移动场景并不完全适合,各种硬件API得不到HTML5原生支持。因此对于WebView的种种Hack、增强应运而生,甚至出现了基于增强WebView提供第三方服务的。

  • 路由:应用内跳转由于加入了WebView而变得复杂起来,同时由于组件化、模块化带来的问题,路由也成为人们讨论的重点。

  • 缓存:移动网络条件差,为了用户体验,必须要做资源缓存和预加载。

  • 通信:即HTML5和Native之间的通信。利用系统提供的桥接API可以实现,不过在应用上还有着一些坑点和安全问题。

这些问题大部分已经有了最佳实践,Rexxar就是其中一个解决方案。在混合开发中一般有两种方案:纯浏览器方案、前端模板渲染容器方案,Rexxar则处于两者之间。

Rexxar的设计者对于Rexxar使用场景有明确的定义:页面是重度展示,并轻度交互的。所以,除了比较简单的应用之外,如果对使用体验有追求,大概很难仅仅用Rexxar,或者其他某种混合开发完成。

对于扩展功能,Rexxar留出了清晰易用的接口。项目中也提供了几个扩展Rexxar功能的实例,文档也较为完整。郭麟他们在豆瓣App中其实也使用相同的接口做了一些扩展,只是由于这些扩展和豆瓣App的业务绑定较深,就没有放入Rexxar项目。

Rexxar在客户端的实现其实就是一个定制了更多功能的WebView。而且,Rexxar使用的是系统的WebView。所以,它对App的体积没有影响。但是,同时使用很多个WebView带来的内存问题,Rexxar同样也有,这是需要注意的。

Rexxar的Crash有两种:

  • 一种是JavaScript的错误,也就是应用逻辑的问题。这类错误他们在WebView中做了捕获,然后通过App的日志系统发回服务器。

  • 一种是WebView的Crash,这种错误WebView自己无法捕获,现在是通过fabric,Umeng这种原生的Crash收集系统收集。

从上线了Rexxar之后,JavaScript,WebView相关错误日志和Crash报告是有增长的。所占的比例和Rexxar的页面数量相关,一直在变化,但都未超过10%。但由于豆瓣App中主要还是原生页面占大多数。所以,Rexxar带来的Crash所占的比例并不大。

他们也正在研究,在移动环境下如何定位Rexxar页面的错误,如何调试,如何修正这些错误,并将其加入基础设施里面。

为什么不用PhonGap/Cordova

在混合开发中早已有了很成熟的方案,就是PhoneGap和它的后继者Cordoba. 为什么豆瓣还要造自己的轮子呢?

郭麟说,如果Hybrid方案定义为前端和原生技术的混合使用,那他们认为PhoneGap/Cordova严格来说不算是Hybrid方案,因为它的目标是全面使用前端技术开发移动应用,而不是前端和原生技术混合使用。但是,包括Cordova,还可以加上React Native,以及Rexxar的目标是一致的:使用前端技术来开发移动应用,提高工程效率。

豆瓣实际上使用PhoneGap开发过一款移动App,并在AppStore上架了,这个应用叫豆瓣音乐人,因此,其实豆瓣对PhoneGap/Cordova已经有一定了解和使用经验。为何在开发豆瓣App时又造了一个叫Rexxar的“轮子”呢?这是因为,他们对PhoneGap/Cordova这个项目的理念并不完全赞同,Rexxar的出发点和PhoneGap/Cordova并不一样。

PhoneGap/Cordova这个项目极具野心。它希望完全使用前端技术完成移动开发。所以,可以看到它尽力让前端技术完成尽量多的开发工作,只在前端无法直接调用的原生系统功能方面提供了前端可用的接口。主流的PhoneGap/Cordova项目将业务逻辑都实现在一个WebView中,目标是,让开发者只使用前端技术就可以完成一个移动应用的所有开发工作。这种做法需要有一个前提:前端技术可以解决移动开发的所有需求。他们认为PhoneGap/Cordova这个理念在现阶段有些过于理想化了,或者说过于激进了。

Rexxar则相对实际,或者说保守一些。郭麟表示,他们仍然认为,现阶段,甚至在相当遥远的未来,移动开发中前端技术都不太可能完全代替原生技术。但同时也承认,移动开发中总是存在部分功能是适合使用前端技术完成的。在他们的认识中,前端技术和原生技术应该是共存的。移动开发中,前端技术不会完全代替原生技术;而有了前端技术的加入,移动开发的效率会提高。基于这种认识,豆瓣开发了Rexxar。

可以看到,Rexxar立足于在一个原生项目使用前端技术,而不是整个项目都使用前端技术实现。他们甚至提供一个页面部分使用Rexxar完成,部分使用原生技术实现的方案。豆瓣希望借助前端技术优秀的排版能力、开发速度、通用性,来弥补原生开发在这方面的不足。在微信作为主要内容分享渠道的今天,这样做还带来了一个额外的好处,Rexxar页面可以平滑的使用在微信中。

总结而言,如果Rexxar和PhoneGap/Cordova比较的话,大目标是一致的:使用前端技术开发移动应用。实现技术栈差不多:使用WebView,提供调用原生功能的接口。但是,出发点不一样。PhoneGap/Cordova致力于完全使用前端技术进行移动开发;Rexxar致力于在移动项目中部分使用前端技术。

移动开发者要学习前端技术

目前,豆瓣移动团队大约有十多位客户端工程师,其中 iOS 和 Android 各一半。另有一位优秀的前端工程师专门支持豆瓣App中的混合开发,他负责Rexxar Web的开发,提供基础设施。同时如果有一些较复杂的业务要用Rexxar实现,他也会参与和指导业务开发。

使用Rexxar这类混合开发技术,使得团队开发的技术栈向前端技术偏斜了。所以,较理想的配置是团队中加入较优秀的前端工程师,由他来处理基础设施的开发,和疑难问题的解决。同时,整个团队需要理解混合开发所带来的优势,认可这个开发方式的转变,并且愿意学习和调整自己的技术栈。

在项目中,在合适的场景中,豆瓣会优先使用Rexxar。在团队中,他们鼓励非前端工程师学习和使用前端技术。为此,他们专门组织了关于前端技术内部培训,让有意愿的非前端工程师具有了可以使用前端技术进行日常开发的基本能力。在豆瓣App的日常开发中,大部分Rexxar页面都由客户端工程师完成,前端工程师会帮忙做Code Review和解决疑难问题。

Rexxar与React Native

豆瓣在实际使用Rexxar的时候,使用React作为前端框架。对此郭麟解释道,Rexxar本身对前端框架的选择没有要求,只是他们选择了React来实现业务层,而当时React Native并未发布,经过对RN的了解后,他们并未否定使用RN的可能性。

在他们看来,React Native同样是一种使用前端技术开发移动应用的技术方案,这和他们开发Rexxar的目的是一致的。只是,Rexxar仍然在停留在浏览器引擎中,而Facebook激进地脱离了沉重的浏览器引擎,架设了他们自己的Web通向Native的桥梁,这是一个很大胆的方案。

在React Native发布后,他们马上就组织研究,并做了小范围的实践,也与同行做了交流。结论是,现阶段,React Native还稍显稚嫩。对于一些技术栈比较特别的团队,比如Web经验特别丰富,前端工程师特别优秀,但又缺乏客户端工程师的情况,React Native是一个快速切入移动应用市场的技术选择。但就豆瓣App的情况和React Native的现状而言,使用前端技术进行移动应用开发方面,他们还坚持留在WebView中,不会使用React Native。

当然,React Native一直在发展和进步。如果,有一天React Native和React可以在代码级别移植,他们也许会尝试从WebView迁移到React Native。毕竟WebView的性能仍然弱于原生。

总结与展望

豆瓣App和研发团队都经历了从小到大的发展过程。Rexxar是这个发展过程中,解决工程效率的一个方案。在豆瓣移动开发中使用Rexxar,确实在一定程度上提高了他们的开发效率。以前一个页面需要 iOS 和 Android 两位工程师各开发一遍,现在只需要一位工程师写一次前端代码,甚至还可以应用到移动 Web 站上去。前端技术开发界面方面开发方面也有效率上的优势。热部署能力,使他们规避了发布移动应用的审核过程,也让bug修复过程更便利。

豆瓣将Rexxar这个项目开源,一方面,是因为提高移动开发的工程效率是一个普遍问题,而他们的实践结果也证明Rexxar确实帮助改善了工程效率。所以,他们认为Rexxar应该能给大家提供一些借鉴的方向。另一方面,是为了提高项目本身的质量,没有方案是完美的,Rexxar也还存在不少问题。开源这个项目,促使他们提高了整个项目的代码质量。同时,也更容易听到大家的意见和建议。

虽然Rexxar仍然存在一些问题和使用上的限制。但是在有限的使用中,豆瓣App团队仍然收获不少。在未来他们会持续推动Rexxar在豆瓣移动开发中的使用。郭麟表示,对于Rexxar未来的发展,他们主要关注两个方面:

  • 一方面是基础设施,比如,如何在产品中,更好地监控Rexxar页面出现的问题,如何调试和解决Rexxar页面出现的bug。如果希望在大型项目中使用Rexxar,这些基础设施是应该配备的;

  • 另一方面是性能,Rexxar仍然跑在浏览器引擎中。浏览器引擎这个中间层提高了工程效率,但也因为性能问题局限了其使用范围。所以,他们会花一些精力提高Rexxar的运行效率。比如,Rexxar的iOS版一直在关注从UIWebView迁移到WKWebView的可能性。

参考文章:

« 微服务的好处和陷阱 CLOSE_WAIT 问题分析 »