从微信小程序原理来看 app 如何搭建专属的 App 小程序生态
从 17 年到 23 年,小程序已经深入人心,吃喝玩乐你都可以找到小程序的身影,疫情期间各种码的场景也给小程序带来了巨大的流量
当然不只是微信小程序,各大平台都推出了自己的小程序,像支付宝小程序、百度小程序、抖音小程序等等,这些 app 都紧跟潮流,实现了自己的小程序框架,经过了五年多时间的发展,小程序的框架已经趋于稳定,对于前端开发来说,甚至出现了一批专门做小程序的开发者
在开发使用上,相信大家在看文档的同时,已经有了自己的认识,但是小程序具体的架构是怎样的?它的原理是什么?我们如何在自己的 app 上搭建一套小程序体系?
当然微信的 webview 的方式也能实现小程序同样的功能,但是和微信的 webview 相比,小程序运行速度更快,因为小程序是双线程模型,逻辑和渲染是分开的,不会相互阻塞
小程序原理
在浏览器环境中,我们都知道,js 代码的执行会阻塞页面渲染,渲染和脚本执行是互斥的,长时间的脚本运营导致页面无响应,这也是为什么 react 要进行切片操作
小程序采用双线程将两者分开,渲染和逻辑独立,互不影响,这就是为什么上面提到的小程序要比正常的 H5 要快,当然要让用户感受到快,首要的就是渲染
目前比较通用的四种渲染技术分别是
webview 渲染
native 渲染
Hybrid 渲染
Skyline 渲染引擎(新增)
首先如果采用 webview 的渲染我们也提到了,同一个线程阻塞导致性能问题,采用 native 的方式做渲染的话我们改动小程序代码还需要同微信客户端一起发包,显然是不可能的,既然两个都不行,那采用 hybrid 的方式呢?将两者结合,比如 react native 就采用了这种方式
那什么是 hybrid 呢?说白了就是一个 app 中既有 native 的内容,又有 web 的内容,原理是其中有一个 UIWebView,里面嵌入了一些 web 页面,这些 web 页面可以跨平台使用,比如 ios 和安卓,做个通用的壳就可以了,你可以把微信类比成 hybrid app,小程序就是一些 H5,界面渲染走的是 web 层面的渲染,然后由端上提供大量的接口提供丰富的客户端原生能力,保证在 web 的体验上能够使用一些原生的能力,并且更新比较迅速
近期微信新增了一种渲染引擎,为什么要新增呢?主要原因是由于 web 发展了这么久,虽然渲染方面已经做的很好的,但是还是由于历史原因以及复杂的渲染流程,让它在 app 中的表现还是有一定的差异,毕竟 js 总是会阻塞页面渲染,所以 skyline 是一种新的渲染引擎,skyline 创建了一条渲染线程来负责 layout, composite 和渲染等任务,并在在端上划出一个独立的上下文,来运行之前 webview 承担的 js 任务、dom 树创建等逻辑。使得 js 不在阻塞页面的渲染,并且很好的保证了兼容性
但是其中的一些特性并不是原生就有,还是需要端上做一些能力的开发和兼容,比如 CSS 的 calc 函数,小程序的 picker-view 组件等等都需要去做适配,成本较高,但是这确实是以后的小程序发展方向,能够较好的提升小程序性能
目前如果没有特殊指定,小程序采用的还是 hybrid 方式
安全
除了渲染要快,对于小程序来说,最重要的一点是安全,对于 web 来说,我可以跳转任意想要的页面,比如从自己的页面跳转到 baidu,跳转到 juejin,都是很随意的,没有任何的管控,但是对于小程序来说不能这样,如果没有约束要跳转的内容,体验会变得很糟糕
另一方面,如果通过 js 代码获取一些用户的敏感数据通过 dom 操作,那用户信息泄漏会将事情变的无法进行
所以基于这些情况,微信内部阻止了一些操作 dom,跳转,动态脚本执行的接口,只提供了一些 js 的脚本执行器,所以小程序提供了一个沙箱环境,这个环境不能有浏览器相关操作,而对于客户端来说,本身微信 app 就有内置的 js 解释引擎,iOS 下是内置的 JavaScriptCore 框架,在安卓则是用腾讯 x5 内核提供的 JsCore 环境,创建了独立的线程去执行 js 代码,这个线程中执行的都是相关的业务逻辑的代码,逻辑相关的内容都在这里处理,渲染相关的都在 webview 中处理,通过逻辑层去控制渲染层的展示,这就是小程序的双线程模型
性能
既然是双线程,那问题来了,线程之间的通信是有延迟的,就导致线程之间的通信实际上是异步的,对于和客户端原生的交互也是异步的,所以小程序的 api 大量采用了回调的方式,比如选择图片
组件
既然渲染是用 webview 来的,那是不是我们直接使用 html 标签就可以了,当然不行,不然利用 a 标签那不是也可以自己跳转了么?所以小程序搞了自己的一套组件系统,名为 Exparser,本质还是模仿了 html 的那一套,但是相对的也增加了自己的一些能力,比如 button,使用一些额外的参数用来获取用户信息,map 可以直接使用地图的能力,ad 的广告能力
通信
小程序和 app 通信原理其本质和 web 同 app 通信的原理类似,只不过有渲染层和逻辑层的通信,因为双线程架构模式,安卓比较简单,不管是逻辑层还是渲染层,都是在 window 对象中注入一些方法,ios 在渲染层采用 messageHandlers 特性,逻辑层则是在 JavaScripCore 框架注入一个全局的原生方法
总结
整套的原理有了,根据这些原理和内容,本质上是可以能够自己实现一套小程序的体系的,但是这个工作量无疑是巨大的,既然这已经是一套成熟的方案,那如何在自己的 app 里面搭件一套小程序环境呢?
市面上已经存在很多开源的方案,毕竟个大厂商都已经有自己的小程序,容器技术已经成熟,比如常见的FinClip,OpenApp,mPaas,Donut 等
我们以FinClip为例,毕竟FinClip能够运行微信中的小程序,并且能够保证用户体验,客户量较大,国内较为领先的小程序容器化公司,我们熟悉的像建设银行 app,工商银行 app 等都有它的身影,有整个一套完整的小程序管理平台,端侧小程序 sdk,以及自身的开发者工具,方便运营开发以及数据分析
像我们上面提到的沙箱环境,双线程的逻辑层和视图层都做成了一套通用方案
所以如果想搭件自己的一套小程序体系,使用现有的方案,安全省心,希望能给需要的同学一定的参考
评论