iOS 动态更新方案 JSPatch 与 React Native 的对比

2016 年 9 月 23-24 日,由 CSDN 和创新工场联合主办的“ MDCC 2016 移动开发者大会• 中国 ”(Mobile Developer Conference China)将在北京• 国家会议中心召开,来自iOS、Android、跨平台开发、产品设计、VR开发、移动直播、人工智能、物联网、硬件开发、信息无障碍10个领域的技术专家将分享他们在各自行业的真知灼见


从8月8日起至9月4日,MDCC大会门票处于6.8折优惠票价阶段,五人以上团购更有特惠,限量供应( 票务详情链接 , 6.8折优惠,欲购从速! ) JSPatch 是 iOS 平台上的一个开源库,只需接入极小的三个引擎文件,即可以用 JavaScript 调用和替换任意 Objective-C 方法,也就是说可以在 App 上线后通过下发 JavaScript 脚本,实时修改任意 Objective-C 方法的实现,达到修复 Bug 或动态运营的目的

目前 JSPatch 被大规模应用于热修复(Hotfix),已有超过 2500 个 App 接入

虽然 JSPatch 目前大部分只用于热修复,但因为其可以调用任意 Objective-C 方法,实际上它也可以做热更新的工作,也就是动态为 App 添加功能模块,并对这些功能模块进行实时更新,可以起到跟 React Native 一样的作用

我们从学习成本、接入成本、开发效率、热更新能力和性能体验这几个方面来对比一下使用 React Native 和 JSPatch 做热更新的差异

学习成本 React Native 是从 Web 前端开发框架 React 延伸出来的解决方案,主要解决的问题是 Web 页面在移动端性能低的问题,React Native 让开发者可以像开发 Web 页面那样用 React 的方式开发功能,同时框架会通过 JavaScript 与 Objective-C 的通信让界面使用原生组件渲染,让开发出来的功能拥有原生APP的性能和体验

这里会有一个学习成本的问题,大部分 iOS 开发者并不熟悉 Web 前端开发,当他们需要一个动态化的方案去开发一个功能模块时,若使用 React Native,就意味着他需要学习 Web 前端的一整套开发技能,学习成本很高

所以目前一些使用 React Native 的团队里,这部分功能的开发是由前端开发者负责,而非终端开发者

但前端开发者负责这部分功能也会有一些学习成本的问题,因为 React Native 还未十分成熟,出了 Bug 或有性能问题需要深入 React Native 客户端代码去排查和优化

也就是说 React Native 是跨 Web 前端开发和终端开发的技术,要求使用者同时有这两方面能力才能使用得当,这不可避免地带来学习成本的提高

而 JSPatch 是从终端开发出发的一种方案,JSPatch 写出来的代码风格与 Objective-C 原生开发一致,使用者不需要有 Web 前端的知识和经验,只需要有 iOS 开发经验,再加上一点 JavaScript 语法的了解,就可以很好地使用,对终端开发来说学习成本很低

可以看一下同样实现一个简单的界面,React Native 和 JSPatch 代码的对比: //React Native class HelloWorld extends Component {
 render() { return ( < View style = {styles.btnArea} > < View style = {styles.btnWrapper} > < TouchableHighlight underlayColor = "#ED5F37” onPress={this.login}              activeOpacity={0.7}>
           登录
         
       
     
   );
 }
 login(){

 };
}

var styles = StyleSheet.create({
 btnArea: {
   justifyContent: ‘center’,
   marginLeft: 20,
   marginRight: 20,
   marginTop: 100,
   flexDirection: ‘row’,
 },
 btnWrapper: {
   backgroundColor: ‘#FC6E50’,
   borderRadius: 5,
   flex: 1
 },
 btn: {
   paddingTop: 10,
   paddingBottom: 10,
   color: ‘#ffffff’,
   textAlign: ‘center’,
 },
}); //JSPatch require ( ‘UIColor, UIScreen, UIButton’ )
defineClass( ‘HelloWord : UIView’ , {
   initWithFrame: function (frame) { if (self = super.initWithFrame(frame)){ var screenWidth = UIScreen.mainScreen().bounds().width var loginBtn = UIButton.alloc().initWithFrame({x: 20 , y: 50 , width: screenWidth – 40 , height: 30 });
   loginBtn.setBackgroundColor(UIColor.greenColor())
   loginBtn.setTitle_forState( “Login” , 0 )
   loginBtn.layer().setCornerRadius( 5 )
   loginBtn.addTarget_action_forControlEvents(self, ‘handleBtn’ , 1 << 6 );    self.addSubview(loginBtn);        } return self;    },    handleBtn: function () {    } }) 接入成本 接入成本上,React Native 是比较大的框架,据统计目前核心代码里 Objective-C 和 JavaScript 代码加起来有 4w 行,接入后安装包体积增大 1.8M 左右

而 JSPatch 是微型框架,只有 3 个文件 2k 行代码,接入后增大 100K 左右

另外 React Native 需要搭建一套开发环境,有很多依赖的库,环境的搭建是一个痛点

而 JSPatch 无需搭建环境,只需拖入三个文件到工程中即可使用

React Native 是大框架,维护起来成本也会增大,在性能调优和 Bug 查找时,必须深入了解整个框架的原理和执行流程,此外 React Native 目前还未达到稳定状态,升级时踩坑不可避免

相对来说 JSPatch 接入后的维护成本会低一些,因为 JSPatch 只是作为很薄的一层转接口,没有太多规则和框架,也就没有太多坑,本身代码量小,需要深入了解去调试 Bug 或性能调优时成本也低

开发效率 在 UI 层上目前 HTML + CSS 的方式开发效率是比手写布局高的,React Native 也是用近似 HTML+CSS 去绘制 UI,这方面开发效率相对 JSPatch 会高一些,但 JSPatch 也可以借助 iOS 一些成熟的库去提高效率,例如使用 Masonry,让 UI 的开发效率不会相差太多

逻辑层方面的开发效率双方是一样的

此外,React Native 在开发效率上的另一个优势是支持跨平台,React Native 本意是复用逻辑层代码,UI 层根据不同平台写不同的代码,但 UI 层目前也可以通过 ReactMix 之类的工具做到跨平台,所以UI层和逻辑层代码都能得到一定程度的复用

而 JSPatch 目前只能用于 iOS 平台,没有跨平台能力

实际上跨平台有它适用和不适用的场景,跨平台有它的代价,就是需要兼顾每个平台的特性,导致效果不佳

跨平台典型的适用场景是电商活动页面,以展示为主,重开发效率轻交互体验,但不适用于功能性的模块

对 Android 来说目前热更新方案十分成熟,Android 十分自由,可以直接用原生开发后生成 diff 包下发运行,这种无论是开发效率和效果都是最好的

所以若是重体验的功能模块,Android 使用原生的热更新方案,iOS 使用 JSPatch 开发,会更适合

JSPatch 也做了一些事情尝试提高开发效率,例如做了 Xcode 代码提示插件 JSPatchX,让用 JavaScript 调用 Objective-C 代码时会出现代码提示,另外跟 React Native 一样有开发时可以实时刷新界面查看修改效果的功能,目前仍在继续做一些措施和工具提高开发效率

热更新能力 React Native 和 JSPatch 都能对用其开发出来的功能模块进行热更新,这也是这种方案最大的好处

不过 React Native 在热更新时无法使用事先没有做过桥接的原生组件,例如需要加一个发送短信功能,需要用到原生 MessageUI.framework 的接口,若没有在编译时加上提供给 JavaScript 的接口,是无法调用到的

而 JSPatch 可以调用到任意已在项目里的组件,以及任意原生 framework 接口,不需要事先做桥接,在热更新的能力上,相对来说 JSPatch 的能力和自由度会更高一些

性能体验 使用 React Native 和 JSPatch 性能上会比原生差点,但都能得到比纯 H5 页面或 hybrid 更好的性能和体验

JSPatch 的性能问题主要在于 JavaScript 和 Objective-C 的通信,每次调用 Objective-C 方法都要通过 Objective-C Runtime 接口,并进行参数转换

runtime 接口调用带来的耗时一般不会成为瓶颈,参数转换则需要注意避免在 JavaScript 和 Objective-C 之间传递大的数据集合对象

JSPatch 在性能方面也针对开发功能做了不少优化,尽力减少了 JavaScript 和 Objective-C 的通信,GitHub 项目主页上有完整的小 App Demo,目前来看并没有碰到太多性能问题

React Native 的性能问题会复杂一些,因为框架本身的模块初始化/React 组件初始化/JavaScript 渲染逻辑等会消耗不少时间和内存,这些地方若使用或优化不当都会对性能和体验造成影响

JavaScript 和 Objective-C 的通信也是一个耗性能的点,不过这点上 React Native 优化得比较好,没有成为主要消耗点

在性能和体验问题上,两者有不同的性能消耗点,从最终效果来看两者差别不大

总结 表1 React Native 与 JSPatch 综合对比 框架 学习成本 接入成本 热更新能力 开发效率 性能体验 React Native 高 高 中 高,跨平台 高 JSPatch 低 低 高 中,不跨平台 高 总的来说,JSPatch在学习成本、接入成本、热更新能力上占优,而 React Native 在开发效率和跨平台能力上占优(见表 1),大家可以根据需求的不同选用不同的热更新方案

JSPatch 目前仍在不断发展中,后续会致力于提高开发效率,完善周边支持,欢迎参与这个开源项目的开发

作者简介: 陈振焯( @bang ),推特中文圈、伊书、JSPatch 作者, 写了十年的博客( cnbang.net )

本文为 《程序员》 杂志 8 月刊特约原创文章,未经允许不得转载,更多精彩文章请订阅 2016年《程序员》

关于移动开发新技术,更多精彩尽在MDCC 2016,详情请查看大会官网: MDCC 2016移动开发者大会



发表回复