ReactNative在游戏营销场景中的实践和探索-背景简介

作者:字节游戏中台客户端团队 - 熊文源

客户端跨端框架已经发展了很多年了,最近比较流行的小程序、Flutter、ReactNative,都算是比较成功、成熟的框架,面向的开发者也不一样,很多大型App都广泛的使用了,笔者有幸很早就参与学习使用了这些优秀的跨端方案,在这几年的开发和架构设计中,除了在App中支撑了千万级DAU,也慢慢将ReactNative跨端方案运用到了游戏,来提升开发、迭代效率。本次文章我们会分5个章节介绍我们在游戏中的一些探索和实践,相信大家也能从中有所收获:

(本篇为系列第一篇)

ReactNative是目前比较流行的跨端方案,目前支持Android、iOS、Windows等平台,能解决了开发中的人力和双端统一性问题,支持热更新,做到了随时随地上线。提到ReactNative,大家一定会和Flutter去做比较,Flutter同样是比较通用的跨端框架,两者各有优缺点,围绕着两者之间的讨论也挺多的,但对于开发者而言,在合适的场景中选择合适的更重要,后面我们也会介绍在游戏中,我们是如何使用ReactNative完成一些活动页面的开发的。

ReactNative作为跨端框架在原生端App中使用比较多,从国外的Facebook到国内各大大厂都在使用,而且基于该设计思想的跨端框架也不少,如weex等,而在游戏中使用的还比较少,主要原因还是游戏的开发、运行原理与原生差异太大。目前游戏的运行环境有很多种,主要以Unity、Cocos、UE4为主,而且这些游戏平台已经具备了跨移动端平台的能力,同时支持Android、iOS等设备,且具备热更新能力。

在原生App开发中很多快速迭代的页面都采用了H5开发,主要集成、开发起来简单,游戏中也比较类似,这些H5页面也做到了多平台同时支持,但在响应速度、启动速度、内存等性能指标上会显得有点不足,而且在游戏环境中很难做到沉浸式的体验。所以围绕着解决活动快速迭代、发布、高性能、沉浸体验等问题,业也做了不少解决方案,参考、学习这些经验我们也做了大量的对比测试,在早期的方案上最终选定了ReactNative作为基础引擎。

游戏环境简介

  • 自渲染引擎:现在的游戏一般都是基于opengl设计,自建的UI渲染引擎,将UI内容更新到原生的surface来显示,所以和原生的UI组件体系差别较大,原生端的系统组件不再适用,且整个游戏在Android设备上是一个Activity,另外游戏自渲染引擎提供了很多动画属性,来满足高质量的动画体验及沉浸式体验,这些在原生侧都是无法共享的。
  • 开发语言差异:在开发语言上也存在很大的差异(如Unity C#/Lua等),不同于Android、iOS的系统开发语言、IDE,相对客户端,参与这方面的开发者也比较少,这也限制了很多原生框架在游戏中的使用,当然游戏也是需要访问设备的一些资源的,这就是常说的bridge,游戏通过bridge来调用系统或者开发者提供的API,UI上仍无法直接共享,虽然网络上也有一些纹理共享的方案打通游戏和原生UI,但使用上仍然有很大的局限性
  • 性能要求高:游戏相比于app来说对画质、渲染性能要求较高,这也导致了自身对内存、CPU占用较高,对于接入的业务、页面的内存峰值、稳定值方面要求比较严格,最好能做到退出页面即释放
  • 热更能力强:游戏一般都支持热更能力,如Unity,本身就支持JavaScript和Lua开发,所以存在unity+Lua的热更方式,且很多活动或者游戏业务都会采用热更和动态入口方式,减少安装包大小,提升灵活性
  • 支持设备复杂:游戏的运行环境除了常见的Android、iOS平台外,还存在PC、Android模拟器等,所以在兼容性和体验上要求比常见的app要高。测试发现现有的Android模拟器一般都是采用x86架构,支持32及64位,而手机设备一般是arm v7、v8,虽然模拟器也支持了v7、v8兼容模式,但都是通过arm转intel指令完成,实测存在很多兼容问题,支持起来难度比较很大

选择ReactNative

从游戏端内的数据来看,除了游戏本身核心外,一些活动、功能都是需要快速迭代的,因此端内用了很多h5的活动场景,且为游戏提供的大量的API和数据能力,但在内存、性能、沉浸式体验上与游戏仍有很大的差距;另外因游戏、H5与原生端方案的差异,原生UI组件无法在游戏中直接使用,需要开发实现,这点比较类似于Flutter,所以为了能更好的兼容原生端的一些能力、场景,选择能支持系统UI交互、跨不同游戏平台,是我们选择的首要考虑条件。从技术上来看,有游戏内的解决方案,有客户端的解决方案,在考虑选择方案时,我们主要考虑了以下几个问题:

  1. 游戏拥有很多不同的平台,而且开发语言不一致,采用游戏端内方案,就会涉及到维护多套引擎的问题,很难做到架构统一性,比较流行的如xLua、PureTS等
  2. 客户端比较流行的跨端方案比较多,上面说的h5页面就能很好的解决跨平台问题,也是目前很多游戏活动采用的解决方案,但因为其性能、体验与原生客户端的差异,才有了后来Facebook对外开源的ReactNative方案,它很好的支持了统一的原生体验,并大大提升了性能,引领了大前端的浪潮。现如今发展比较迅速的Flutter,自渲染引擎和UI一致性,也逐渐被很多大厂App采用;另外国内友商也提出了自己的跨端方案Weex,原理上与ReactNative类似。

为什么没有选择Flutter、weex作为我们游戏端跨端引擎呢?相比而言Flutter的工程化较为复杂、整体偏重,而且很难适应游戏和活动业务分离开发的场景,而weex因为生态与ReactNative的差距,也不在我们视角之内;另外游戏端内的xLua+Unity、及腾讯已开源的pureTS也是业内用的比较多的方案,我们也一起做了对比分析:

ReactNative Flutter xLua PureTS
开发语言 React Dart lua TS
运行环境 JS(JSCore、hermes) Flutter engine unity unity+JS(Qucik js)
支持平台 Android、iOS、web Android、iOS、web Android、iOS Android、iOS
生态 丰富(react) 较少(dart) 较少 较少
代表App 京东、美团、携程 闲鱼、美团 unity游戏 腾讯潘多拉
热更能力 支持 需改造(android) 支持 支持
稳定性 稳定(2015发布) 较稳定(2017发布) 稳定 较稳定(2020发布)
工程化 简单 中等 中等
学习难度 简单 中等
UI组件 丰富、原生(生态+自研) 较少(skia) unity组件 unity、ue4组件
开发工具 方便(vs code) 依赖原生IDE unity IDE 方便(vs code)
动画、渲染 较丰富 丰富 丰富 丰富
适合场景 全页面、弹层 全页面 unity页面 unity页面

其中xLua、PureTS采用的是游戏端内的UI渲染,在游戏内部是比较成熟的方案,之所以不在我们前期的评估的范围之内的原因如下,也不是方案不好,而是不适合,当然采用ReactNative 原生端方案也有局限性,如UI无法和游戏混排,这也是为什么完成ReactNative搭建后,也开始持续迭代支持了PureTS方案的原因,具体原理这里就不解释,这是一个开源项目,原理不算复杂:

  1. 两者采用的是游戏UI组件,开发者必须对游戏本身的设计和架构有很深的了解,比较适合有丰富游戏开发经验的团队,而我们是客户端团队
  2. 这些方案都是针对某个游戏平台而设计,不具体全平台统一性,需要大量适配支持Cocos、Unity、UE4等平台,维护成本较高
  3. 很难复用客户端很多复杂的组件,例如地图、直播、地图等等的组件,这些在游戏中就不支持,自然这些方案也很难支持

相信大家还是会有疑问,选择ReactNative感觉不是一个最好的选择,相比于Flutter的最近的突飞猛进发展,ReactNative逊色了太多,这两年进展微乎其微,而且渲染性能的瓶颈也越来越制约了其发展,先后有很多开发者都宣布不再开发、维护ReactNative,转向原生开发或者Flutter的怀抱,但我们最终还是坚定的选择了reactnative,更看好其未来的架构发展,详细大家可以参考我的文章《庖丁解牛!深入剖析React Native下一代架构重构》,同时在后面的章节中,也会为大家重点讲解新架构的特点。