用户
 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,登录网站

小程序社区 首页 教程 查看内容

原生小程序架构及同构方案

Rolan 2020-7-23 00:14

前言最近实习中参与了H5项目向小程序迁移的工作,在微信官方文档和一些帖子上学习了小程序运行机制和底层原理,以及与Web页面的区别,在此基础上又看了一些关于小程序同构方案的内容。以下是我个人的一些学习总结。 ...

前言

最近实习中参与了H5项目向小程序迁移的工作,在微信官方文档和一些帖子上学习了小程序运行机制和底层原理,以及与Web页面的区别,在此基础上又看了一些关于小程序同构方案的内容。以下是我个人的一些学习总结。本文内容参考

微信开放文档

如何理解小程序的运行机制

小程序多平台同构方案

小程序是什么?

在小程序诞生前,微信团队开发的JS-SDK使web开发者可以通过暴露的API使用微信原生能力去完成一些事,如调用接口打开微信支付等。针对移动端设备网络状态不稳定导致的白屏问题,微信又推出增强版JS-SDK,也就是“微信 Web 资源离线存储”,但在复杂的页面上依然会出现白屏的问题,原因表现在页面切换的生硬和点击的迟滞感。这个时候需要一个JS-SDK处理不了的,使用户体验更好的一个系统,即小程序。

小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验。

其本质是运行在webview上的H5应用,但与H5又有着本质上的不同。H5可以理解为运行在移动端的web页面,本质还是由HTML+CSS+JS构成的web应用。小程序和H5的区别也就是小程序和网页的区别。

小程序与普通网页开发的区别

小程序的主要开发语言是 JavaScript ,小程序的开发同普通的网页开发相比有很大的相似性。对于前端开发者而言,从网页开发迁移到小程序的开发成本并不高,但是二者还是有些许区别的。

  • 网页开发的渲染和脚本执行是在同一个线程上执行的,这也是网页脚本长时间运行有可能会导致页面失去响应的原因;而小程序的视图层和逻辑层是完全分离在两个不同的线程上执行
  • 开发网页时我们可以在JS代码中通过Dom API对节点进行各种操作,通过window对象实现原生事件响应、页面跳转;由于小程序的JS代码运行在JSCore,与渲染层分离,所以在逻辑层中无法获得Dom和Bom,从而无法使用各种Dom API
  • 网页开发者需要面对的环境是各式各样的浏览器,PC 端需要面对 IE、Chrome、QQ浏览器等,在移动端需要面对Safari、Chrome以及 iOS、Android 系统中的各式 WebView 。而小程序开发过程中需要面对的是两大操作系统 iOS 和 Android 的微信客户端,以及用于辅助开发的小程序开发者工具

小程序架构

渲染机制

处于性能和实现的考虑,小程序采用 Hybrid渲染机制 ,这样做有几点好处:

  • 扩展 Web 的能力。比如像输入框组件(input, textarea)有更好地控制键盘的能力
  • 体验更好,同时也减轻 WebView 的渲染工作
  • 绕过 setData、数据通信和重渲染流程,使渲染性能更好
  • 用客户端原生渲染内置一些复杂组件,可以提供更好的性能

架构

如下图所示,原生小程序框架采用双线程模型:视图层和逻辑层完全分离为两个不同的线程。每个页面的渲染在一个webview线程上执行,视图层包含多个webview线程,而逻辑层则统一在JSCore上执行。

这样做的目的是防止逻辑层对Dom和window的操作(如跳转到外部页面),使整个应用变得安全可控。

  • 逻辑层:创建一个单独的线程去执行 JavaScript,在这里执行的都是有关小程序业务逻辑的代码,负责逻辑处理、数据请求、接口调用等
  • 视图层:界面渲染相关的任务全都在 WebView 线程里执行,通过逻辑层代码去控制渲染哪些界面。一个小程序存在多个界面,所以视图层存在多个 WebView 线程
  • JSBridge 起到架起上层开发与Native(微信系统)的桥梁,使得小程序可通过API使用原生的功能,且部分组件为原生组件实现,从而有良好体验

视图层和逻辑层的通信

双线程模型下,逻辑层代码无法直接操作Dom,逻辑层和视图层的数据传输(setData)是通过两边的evaluateJavaScript实现的。用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。

小程序多端同构方案

很多企业都有自己的小程序平台,如微信、支付宝、头条等,如今市面上很多产品都是基于React、Vue等框架开发的web应用,但web端代码是不可能运行在小程序平台上的(详见上述小程序和web应用的不同),而开发几套代码的时间和维护成本又太高,为了节省学习和开发成本,各大公司都推出了自己的多端小程序方案,使开发者可以用React、Vue框架来开发小程序。类似框架有微信的Kbone、阿里的Remax、京东的Taro等。

Taro是在编译时将代码适配到小程序平台,而Kbone和Remax则是在运行时完成这个工作。

以下重点解释 Kbone 和 Remax 。

Kbone

参照微信官方文档,Kbone在适配层里模拟出了浏览器环境,让 Web 端的代码可以不做什么改动便可运行在小程序里。

kbone实现原理是在worker线程适配了一套JS Dom API,上层不管是哪种前端框架(react、vue)或原生JS最终都需要调用JS Dom API操作 dom,适配的 JS Dom API则接管了所有的Dom操作,并在内存中维护了一棵Dom tree,所有上层最终调用的Dom操作都会更新到这棵Dom tree中,每次操作(有节流)后会把Dom tree同步到webview线程中,通过wxml自定义组件进行 render。

Remax

与Kbone上层支持多种框架(React、Vue、Angular)不同,Remax专门实现React应用向小程序的适配。

Remax实现原理是在worker线程维护一棵虚拟Dom tree,这棵虚拟Dom tree会通过小程序原生的setData方法映射到render线程,render层再把虚拟Dom tree进行遍历然后渲染。

Remax和kbone类似,都是在 worker 线程维护一棵Dom tree,再把这棵 Dom tree传到render线程进行渲染,唯一的区别是remax dom tree发生变化时,会计算差异,而不需要把整棵树都传到render线程,此功能是react提供的,就是在 diff 完后找出差异,则把差异传到render线程

总结

  • Kbone和Remax实现原理基本相同,都在worker线程维护虚拟Dom tree,再把虚拟Dom tree传到render线程渲染
  • 二者主要有两点不同:Kbone上层支持多种框架,而Remax仅支持React;Remax的Dom tree发生变化时会计算diff,把diff映射到render线程,而Kbone是将整个Dom tree传过去
鲜花
鲜花
鸡蛋
鸡蛋
分享至 : QQ空间
收藏
原作者: 菜菜的电冰箱 来自: segmentfault