配合 APP 调用 JS 的一次尝试

项目初衷

最初的场景是用户在对购物车的操做中,因为用户对购物车的每次操做(包括选择,调整数量)都须要计算商品的促销和分组的状况,而这段逻辑的计算都须要调用后端的接口,那么瓶颈来了:node

  • 请求时间长——一次 HTTPS 的请求对于 web 性能有很大的影响,尤为是对于移动端来讲,用户所在的网络情况直接影响请求延时的长短。
  • 数据计算量大——少许的计算看起来不会有太多影响,但与之叠加的业务逻辑和大量的数据计算将隐性增长时间的消耗和出错的概率。
  • 交互卡顿——上述两个时间上的消耗将直接致使用户操做的障碍,特别是对于购物车中调整数量和选中的操做。
  • 多端统一——对购物车的操做是 APP 和 WAP 多端统一的操做,须要收敛管理,若是后端再也不适合处理,那么发布统一语言的、多端共同调用的 JS 功能包将是个不错的选择。

抹平差别

APP 中调用 JS 的基本思路就是使用内嵌的 JS 引擎,与 Chrome 的 V8 引擎不一样,iOS 使用的是自带的 JavaScriptCore;而 Andriod 则引用了 Duktape。这里还有许多其余的引擎。android

因为调用平台不一样,JS 引擎也不一样,要想使得 JS 在多端输入输出保持一致,须要了解:git

  • 代码的管理方式
  • 对于原生方法的支持

如表格:github

WAP iOS Andriod
代码管理 modules JSContext duktape.evaluate
原生支持 caniuse Safari duktape

对于代码的管理,WAP 下支持正常的模块化写法和调用;iOS 提供的 JSContext 能找到 JS 中对应的对象和方法;Andriod 下 duktape-android 只提供了 evaluate 解析字符串并在 runtime 模式下调用(因此 Andriod 下执行较慢)。后两种直接屏蔽了模块化的写法,最终方案只能选择原始的对象管理方法的形式。web

对于原生方法的支持,WAP 下因为跟机型和原生浏览器相关,可在 caniuse 上查找;iOS 中的 JavaScriptCore 暂时没查到具体的支持状况,因为 Safari 下使用相同的 JS 引擎,可查询对应版本的 Safari 的支持状况;duktape 因为是开源的,很容易查询。所以只要注意调用方法的兼容,以及跟 APP 端的调试,便可避免。后端

Tips:本项目在调试中就发现 JavaScriptCore 缺乏 Array.prototype.find 原生方法的支持,对 Array.prototype.sort 的实现效果与 V8 也不太同样。浏览器

代码调试

项目开发中最困难的地方在于代码的调试,经过本地 node.js 测试的代码不必定能在 APP 的 JS 引擎上跑通(例如对原生方法的支持上)。因为相似在两个不一样的 REPL 中调试,目前没有什么太好的版本,只能在调试代码中尽可能抛出全部可读异常,而后在 APP 的 JS 引擎中捕捉到的异常信息分析问题。安全

脚本安全

参考 JSPatch 部署的安全策略,主要分为传输安全执行安全服务器

传输安全作了两件事:网络

  • HTTPS 传输——将 JS 文件放在支持 HTTPS 的服务器上,保证传输中泄露和劫持的安全性。
  • RSA 校验——在服务端对 JS 文件内容作了 MD5 校验,并发送给 APP。客户端根据公钥解密,保证文件没有被纂改。

执行安全上,因为不像 JSPatch 须要 JS 调用 APP 的功能,安全性上相对较小,只要 APP 对 JS 文件的执行异常作出处理便可不会形成 APP crash。固然这种重要的逻辑,JS 的单测和较高的测试覆盖率是必不可少的。同时 APP 也可对 JS 的执行进行监控上报,对支持 JS 的版本实行灰度发布。

版本控制

这是该项目的红利所在。因为是调用 JS 文件,所以 JS 逻辑的更新免去了 APP 发版的苦恼。新版本的 JS 文件由接口经过文件名控制版本并下发到客户端,客户端校验 MD5 经过后便可使用新的 JS 版本。

后续

在 APP 中调用 JS 的方式无疑缓解了请求资源的消耗版本控制的烦恼,同时也保证了逻辑的统一。但大规模的使用,必将考虑到 JS 的执行效率、平台的差别以及业务方的需求。实际的效果如何,还需进一步的探讨。

相关文章
相关标签/搜索