微信小程序这两天被传的热火朝天。相比传统应用需要安装对应的app而言,腾讯这次推出的微信小程序以微信app作为入口平台,第三方应用运行在微信环境上,从使用上来讲,其类似于网页浏览,打开某个小程序链接便可以使用,访问结束后直接关闭,本地无需安装其它app,官方宣称其具备与原生同样的用户体验。小程序与传统web页面的主要区别在于,web页面是完全运行在客户端的浏览器环境下,小程序则更多地依赖于本地组件,例如调用本地视图类来显示内容,而不是通过浏览器来渲染,所以从性能上讲,小程序的性能将超过web,用户体验也会更好。
目前由于微信小程序还处于内测阶段,现在对其原理细节还不太清楚,但现在已经有很多网络大咖指出微信小程序应该是使用了react native的来实现的。本文则主要对React Native iOS的实现原理进行一定的分析。虽然微信小程序不一定直接使用React native,但至少应该是借鉴了其设计精髓。
“如何卖土豆”
在iOS开发当中,一个比较典型的需求是后台希望能够对客户端某些属性进行动态配置,比如像视图显示:现在非常流行的“千人千面”。这是目前传统客户端所能够做到的,后台提供数据给客户端,客户端根据数据来对自身进行配置。更进一步,公司每天都会有新的业务产生,后台希望能把这些业务展示给用户,比如一家提供视频服务的公司突然决定拓展业务开始卖土豆,这时客户端开始犯难了,由于之前客户端只是播放视频,现在突然要卖土豆了,客户端并没有代码来实现卖土豆控制逻辑,现在后台只能配置数据,但控制逻辑又怎么告诉客户端呢。传统遇到这个问题的时候有两种办法,一种是客户端增加卖土豆的代码,发一个新app版本,用户必须升级到最新的版本才能买土豆,另一种方法,如果客户端集成了webview,后台可以通过开发web页面来实现买土豆的功能,所有操作通过web交互来实现。React Native的出现就是解决了业务逻辑下发的问题,除了数据之外,后台可以将业务代码下发到客户端,客户端根据下发的逻辑实现完全新的功能,实现了真正意义上的“动态应用”。
React Native核心——js引擎
React Native通过编写js代码,来实现本地应用的构建,这是如何实现的呢?首先一点,iOS目前还是比较封闭的,js代码是无法直接来对iOS应用进行构建,其必须通过其它途径来实现。React Native巧妙的使用了iOS的js引擎来实现js到Object-C转接的功能。js是一门脚本语言,只有在运行时才会进行语法分析,iOS提供了JavaScript Core框架,这是个js引擎,可以执行js代码,例如:
JSContext *context = [[JSContext alloc] init];
JSValue *jsVal = [context evaluateScript:@"21+7"];
int iVal = [jsVal toInt32];
React Native创建了一个单独的线程来执行js代码,其制定了一套转义规则,通过React Native对外提供的接口,来实现js代码到Object-C的转换。这种思想其实在之前已经存在,比较典型的案例是cordova,前端通过js bridge来调用客户端功能模块,其原理也是通过webview的js引擎来实现转义。React Native在这基础上走得更深、更远。不再局限于某个功能模块的调用,而是要在应用的根基上,完全实现一个全新的app。
React Native工程分析
React Native的环境搭建可以参考:
http://reactnative.cn/docs/0.31/getting-started.html#content
使用react-native init AwesomeProject命令可以创建一个名为AwesomeProject的React Native的工程。下面是创建好的工程目录,Libraries目录下存放的React Native的客户端核心代码,其由若干个子工程组成。
通过Xcode在模拟器中启动应用,项目会执行脚本开启终端来执行node命令,效果如下,从打印内容来看,是启动一个服务器。
应用运行效果如下图所示:
在工程目录里面有一个index.io.js文件,其便是构建ios应用的js核心代码。
index.ios.js内容如下所示:
上面展示了整个工程的结构及js代码。那么在应用运行时,React Native是如何将js代码发送给应用的呢?通过对代码进行分析,发现在应用启动后,会创建js代码URL地址,如下图所示:
其中jsBundleURLForBundleRoot内部会调用下图的方法,其会创建一个完整的URL,通过调试发现其最终生成这样的地址:
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false
通过浏览器访问该地址返回得到下面的结果,是一个js代码文件。
搜索其中内容找到自己创建的部分,发现其已经被转义成了原生js代码。
通过上面的分析,可以了解其中的原理,我们编写的React Native js代码需要在后台经过一次转义,将代码转义成原生的js代码后,发送给客户端,客户端再将其放入到js引擎中来运行。服务器端最终将所有的代码都整合到一个js文件当中,发送给客户端。为了验证这个猜想,我将js代码保存到本地文件,将其放在http服务器上,通过http://localhost:8080/examples/index-ios.html来访问该文件,通过对工程代码进行修改,将返回的url改成上述目标,发现工程能够正常运行。
由此可以整理出React Native的整个运行过程:
微信小程序
如果微信小程序的确是借鉴了React Native的思想,那么其整体的运行原理应该如上面分析的一样。微信有可能会在此基础上做一些优化或增强。例如在上面的测试过程中发现,下发的js文件,单只实现了一个hello world的功能,其文件大小就有1.5M,这是由于其包含了React Native的js核心代码。如果微信需要减少数据交互,则很有可能会将Native代码转义原生js代码的过程放在客户端来完成,或者通过某些方式,将重用的核心代码放在本地,数据交互只更新业务代码,另外在代码安全上有可能会做一些增强工作。从目前透露的消息来看,微信提供的本地接口还是非常丰富的,对绝大部多数应用来讲都是满足的。
小程序的前景:
从功能上讲,微信小程序与之前UC、百度推广的轻应用并没有很大区别。但由于微信拥有巨大的流量优势,其所带来的影响是不可比拟的。本地化在提升运行速度的同时也提供了更多的权限,公司可以开发出各种功能复杂的应用,给用户更为丰富的体验。在应用推广上将会非常方便,未来很有可能会产生多个超级小程序。
小程序同时也面临着不少挑战,像微信需要在apple store通过审核才能发布,如果微信成为了应用的入口,这将抢去apple store的市场,apple也不会容忍这种情况发生。同时,应用的发布将通过微信来完成,应用的安全审核,按理都需要微信来做,这对微信来说也是非常大的挑战。对于第三方公司而言,在微信上使用小程序来带来利益的同时,也面临着微信的审查压力,之前就出现过订阅号被封的情况,如果出现这种情况将会对公司带来致命的打击,公司也不会将流量全部分到小程序当中。
“小程序”能否代替App
HTML5与App还是存着本质的区别:App功能极为复杂,而HTML5基本上只有简单的一个功能,这种差别就像早年间的flash小游戏和大型单机游戏之间的差别,“小程序”根本无法替代App。
“小程序”主打“用完即走”、无需安装和卸载的模式,这对于用户来说方便快捷,但对于产品而言,却失去了沉淀用户最基本的方式。这里可以看到,APP获取一个用户的门槛是高的,但高门槛带来的好处是,用户的二次消费门槛低了。
而H5虽然首次消费门槛低,但却遇到了后续消费门槛无法降低的问题。而这方面正好是APP的优势。
关于微信和手机操作系统
很多人可能会觉得微信的未来就是手机操作系统。但微信基本不可能这么定位自己。因为,手机操作系统的核心展示是APP收藏夹,而微信是聊天窗口。这个本质不改变,就很难改变“应用APP”和“小程序”在各自体系里的地位。
手机操作系统未来依然是APP的天下,侧重重体验、重交互、高粘性需求的产品。比如微信就是这样的产品。
设想微信就是一款基于浏览器的H5产品,估计你用起来就很崩溃了。
参考资料: