手机版

从小程序不支持DOM操作的事实出发 深入分析小程序的运行机制

时间:2021-12-03 来源:互联网 编辑:宝哥软件园 浏览:

小程序现在如火如荼,各大公司都推出了自己的小程序平台。目前看来运行机制差不多。数据形成视图、渲染和逻辑分为两个线程,通过线程通信实现交互。

刚接触小程序开发的时候,看到小程序的语法很奇怪。看着react和vue的组合,我想知道为什么要花这么多精力来实现这样一个机制。是为了体现技术nb吗?用了一段时间,发现了问题。复制pc开发的思想不方便,特殊的小程序不支持dom相关的api。我看了很多次微信和支付宝小程序的官方文档,终于有了一点了解。

这篇文章大部分是官方文件引用加上一点我自己的总结。

Web开发渲染线程和脚本线程是互斥的,这就是为什么长时间脚本运行可能会导致页面失去响应。开发人员可以使用各种浏览器公开的DOM API来选择和操作DOM。在小程序中,它们是分开的,运行在不同的线程中,而逻辑层运行在JSCore中,没有完整的浏览器对象,所以缺少相关的DOM API和BOM API。

由于支付宝的官方文档过于简略,本文结合了微信和支付宝小程序的特点,如有不同,请指正。

1em; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, Tahoma, Arial, STXihei, "Microsoft YaHei", 微软雅黑, sans-serif; background-color: rgb(254, 254, 254);">这部分在微信和支付宝小程序官方文档都有说明

浏览器环境中渲染线程和js线程是互斥的

由于JavaScript是可操纵DOM的,如果在修改这些元素属性同时渲染界面(即JS线程和GUI线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。

小程序页面文件结构

小程序分为 app 和 page 两层。app 用来描述整个应用,page 用来描述各个页面。

app 由三个文件组成,必须放在项目的根目录。

文件必需作用app.js是小程序逻辑app.json是小程序全局设置app.acss否小程序全局样式表

page 由四个文件组成,分别是:

文件必需作用app.js是页面逻辑app.axml是页面结构app.json否页面配置app.acss否页面样式

为了方便开发者减少配置项,描述页面的四个文件必须具有相同的路径与文件名。

单逻辑线程与多webview渲染线程

小程序的逻辑层和渲染层是分开的两个线程,小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS脚本工作在逻辑层。在渲染层,宿主环境会把WXML转化成对应的JS对象,在逻辑层发生数据变更的时候,我们需要通过宿主环境提供的setData方法把数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的Dom树上,渲染出正确的UI界面。

小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由客户端做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。

从小程序不支持DOM操作开始深入分析小程序运行机制(图1)

从逻辑组成来说,一个小程序是由多个“页面”组成的“程序”。宿主环境提供了 App() 构造器用来注册一个程序App,需要留意的是App() 构造器必须写在项目根目录的app.js里,App实例是单例对象,在其他JS脚本中可以使用宿主环境提供的 getApp() 来获取程序实例。

小程序开发框架的逻辑层使用 JavaScript 引擎为小程序提供开发者 JavaScript 代码的运行环境以及微信小程序的特有功能。 逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。 开发者写的所有代码最终将会打包成一份 JavaScript 文件,并在小程序启动的时候运行,直到小程序销毁。这一行为类似 ServiceWorker,所以逻辑层也称之为 App Service。

const app = getApp(); 复制代码

参考资料:微信1、微信2、微信3

小程序的运行环境

js运行引擎

小程序的 JavaScript 代码分为逻辑层脚本和 sjs/wxs 脚本

支付宝文档说sjs和逻辑层运行在相同的 JavaScript 引擎的不同线程中。

微信文档又表示wxs是运行在webview中的,并且提供了更为强大的功能:如果在 iOS 设备上小程序内的 WXS 会比 JavaScript 代码快 2 ~ 20 倍,在 android 设备上二者运行效率无差异;减少通信的次数,让事件在视图层(Webview)响应;用来响应小程序事件,目前只能响应内置组件的事件,不支持自定义组件事件;还能调用逻辑层的事件;

对两者sjs/wxs差别表示吃瓜状态,支付宝的sjs明显功能弱了很多,毕竟鸡肋,一般用来模拟vue里的compued功能使用,无法作为事件回调。微信的wxs提供了更强大的支持。

试了下sjs不带类似computed缓存功能

从小程序不支持DOM操作开始深入分析小程序运行机制(图2)

两个平台都会对新预发的代码进行 babel 转换,使 JavaScript 引擎支持绝大多数 ES6 的新特性,但是对于内置对象未提供完全的Polyfill,具体支持情况可以查阅支付宝、微信

版权声明:从小程序不支持DOM操作的事实出发 深入分析小程序的运行机制是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。