最近几年,钉钉小程序、微信小程序、支付宝小程序等号称拥有Native体验,前端移动App页面开发方式如雨后春笋般地涌现出来,为开发者和用户提供了一种轻量级的App体验。作为一种不需要下载和安装即可使用的应用,它们实现了应用“触手可及”的功能,用户扫一扫或者搜一下即可打开应用。它们也体现了“用完即走”的理念,用户不用关心是否安装太多应用的问题。而在这个产品快速开发迭代的时代,App动态化也是迫在眉睫。所以,掌握这种轻量级的App开发,已成为每个前端和客户端开发者的必备技能。
本节以iOS端的钉钉小程序为例,带读者了解这些轻量级App的原理。
其实,小程序本质上区别于React Native和Weex,它是运行在WebView容器中的,总体来说,它采用了传统的移动端 H5浏览器作为页面运行环境,但是与传统的B/S结构的Web应用不同,它没有Document、Window等对象,却为用户提供了普通H5页面无法达到、近似原生App的控件体验,同时向开发者提供了功能丰富的API,如自定义的标签语言AXML、样式语言ACSS、JSON配置和自定义的小程序的JSAPI,如图2-1所示。
图2-1 小程序的工作原理
Page页面用来承载小程序的各个页面,表2-2展示了 Page页面的组成部分。
表2-2 Page页面的组成部分
由小程序底层封装的AXML,可以使得开发者通过使用简单的类似HTML的语言进行编写,调用AXML定义好的自带复杂交互的组件。WKWebView负责对AXML和ACSS进行解析和执行,开发速度提升的同时,比使用H5开发相同复杂度的组件的计算渲染速度更快。小程序的JavaScript解析则是直接由JavaScriptCore负责的,页面内部的交互行为将继续通过JavaScript实现,而与App的交互将会解析为Objective-C来与钉钉iOS客户端交互。
.json文件其实就是一种配置文件,是小程序与钉钉客户端的约定,直接由Native读取来控制整个小程序App或者页面的一些生命周期、导航边框等通用行为样式。
所以钉钉小程序本质上就是自定义了多功能标签、页面配置项,优化了传统H5和Native交互,采用了更高效的渲染引擎和更高效的JavaScript解析引擎的类H5的网页开发,当然由于各种适配与钉钉客户端的自定义功能,高效的同时,它也只能在钉钉中运行。
1.WKWebView简介
WKWebView是苹果公司在iOS 8之后推出的WebKit框架中的浏览器控件,其加载速度比UIWebView更快,但内存占用率下降很多,解决了加载网页时的内存泄漏问题。
对比UIWebView,WKWebView最大的优势在于:
● 更多地支持HTML5的特性。
● 具有官方宣称的高达60fps的滚动刷新率及内置手势。
● 拥有与Safari相同的JavaScript引擎。
● 更多内容可参考官方文档“链接0”。
2.JavaScriptCore简介
JavaScriptCore建立起Objective-C和JavaScript两门语言之间沟通的桥梁。无论是这些流行的动态化方案、WebView Hybrid方案,还是之前广泛流行的JSPatch,JavaScriptCore都在其中发挥了举足轻重的作用。
iOS官方文档对JavaScriptCore的介绍很简单,其实主要就是给App提供了调用JavaScript脚本的能力。而在小程序中钉钉Native也是通过JavaScriptCore调用JavaScript脚本的。
其中最重要的几个模块如下:
● JSContext.
● JSManagedValue.
● JSValue.
● JSVirtualMachine.
图2-2展示了Objective-C和JavaScript的类型转换。
图2-2 Objective-C和JavaScript的类型转换
WKWebView及JavaScriptCore提供了小程序的运行环境。WKWebView负责对AXML和ACSS进行解析和执行,并渲染和展示。JavaScriptCore(Android是serviceWork)提供了开发者所写的逻辑代码(JavaScript)的运行环境,该运行环境被称为Service(没有Document、Window等对象),Service中的代码与WebView中的代码完全隔离,如图2-3所示。
图2-3 小程序前端框架
通俗来说,在小程序中JavaScript逻辑的运行和视图的运行是在两个不同环境中的,App Service通过底层架构来操作视图。因为JavaScript和视图(DOM所在)没有运行在同一容器中[在传统H5,JavaScript和视图(DOM所在)运行在同一容器中],且小程序的JavaScript逻辑是用JavaScriptCore来解析的,JavaScriptCore没有Document、Window等对象,所以小程序不能使用DOM操作(并不是真的没有DOM)。每启动一个Page页面,会有一个Render容器启动WebView+Service,所以层级过多的小程序也是不推荐的。
一个小程序页面对应一个 Service,客户端通过 JavaScriptCore为开发者的Service代码提供运行环境;一个小程序可能有一个或多个Page作为向用户展示内容的交互页面,客户端由WKWebView提供Page解析和渲染支持;页面与页面之间的通信通过Service环境中转。
基于上文,小程序的性能在以下方面明显优于H5页面。
● 网络请求。
AXML定义好的自带复杂交互的组件,使得小程序所需加载的代码量更少,网络请求时间优于传统H5页面。
● 页面渲染。
WKWebView负责对AXML和ACSS进行解析和执行,降低了计算的复杂度,并提高了渲染速度。
● JavaScript计算与客户端交互。
由JavaScriptCore直接进行JavaScript解析与计算,以及与客户端的交互,比传统H5页面依托于浏览器内核的JavaScript解析更友好。JavaScriptCore可以将JavaScript代码转换为Objective-C直接运行在Native App中,因此小程序与Native的交互等行为更快速,功能也更强大。
● 应用可以使用原生控件。
通过小程序框架开发出的小程序,实际上是一种混合模式的页面,一些在H5页面中交互复杂的组件、性能较差的组件,在这里可以直接替换为对应的 Native原生控件,其在用户体验性能上自然好于传统H5页面。