爱收集资源网

微信小程序架构图,你了解多少?

网络 2023-07-02 07:02

前言

万事开头难,先来上一张图以表诚心。

该图为陌陌小程序的整体构架图,详细解析会在下边的整体构架中讲,主要先让你在脑中有点印象,下面我们就开始本篇的愉快旅程吧。(=^▽^=)

发展来历

我们先来简单讲讲陌陌小程序的发展历,知己知彼方能百战不殆。微信小程序简称小程序。张小龙于2017年01月09日在陌陌公开课上宣布其即将上线。小程序英文名为 Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。

小程序上线以来,一直被称为便携版的 APP,关于二者之间的区别,无外乎是小程序相对轻便、开发成本低、开发周期短、收效快。

小程序并非陡然冒下来的一个概念,当陌陌中的 WebView 逐渐成为联通 Web 的一个重要入口时,微信就有相关的 JS API 了。

WebView 是移动端(手机、IPad)提供的运行 JavaScript 的环境,是系统渲染 Web 网页的一个控件,可与页面 JavaScript 交互,实现 APP 与 Web 的混和开发,WebView 渲染 Web 页面须要强悍的渲染内核支持,这其中 Android 与 IOS 系统的内核又有所不一样。

根据了解,小程序诞生的背景主要推动力是因为联通网页在陌陌内传播体验不良,能力不强,当然我认为这其中也有原生 APP 缺点缘由的推进,比如每次都要从 App Store 或者其他应用市场下载,即使下载了,也抢占系统很大的空间,如果不常常用,被用户删除的可能性也十分大。

我们先抛掉原生APP的问题不谈,对于联通网页在陌陌内传播体验不良,能力不强的问题,即使后来陌陌团队推出了 JS-SDK 来解决联通网页能力不足的问题,但 JS-SDK 的模式并没有解决使用联通网页遇见的体验不良的问题,这其中的诱因大约能概括为这三个点:白屏问题、页面切换的粗俗和点击的迟滞感。

为了解决这种问题,微信团队面临的问题是怎样设计一个比较好的系统,使得所有开发者在陌陌中都能获得比较好的体验。这个问题是之前的 JS-SDK 所处理不了的,需要一个全新的系统来完成,它须要促使所有的开发者都能做到:

这就是小程序的来历。

宿主环境

微信小程序的寄主环境为微信客户端,它是依赖于微信客户端上运行的,并且跟小程序 基础库 版本有重大关联关系。

我们可以把 微信客户端 以及 小程序基础库 简称为陌陌小程序的寄主环境。

微信小程序可以调用寄主环境提供的微信客户端的能力,可以完成许多普通网页未能完成的功能,这就促使小程序比普通网页拥有更多的能力。小程序会运行在不同版本(不同的陌陌客户端+不同基础库)的寄主环境下,因此针对各个版本的寄主环境做程序上的兼容也是在所难免的。

微信小程序 遮蔽层_架构解读_微信的架构师

执行环境

小程序的主要开发语言是 Javascript,它与传统网页开发具有相似性但还是有一定区别:

微信小程序运行在多种平台上:iOS(iPhone/iPad)微信客户端、Android 微信客户端、PC 微信客户端、Mac 微信客户端和用于调试的陌陌开发者工具。

各平台脚本执行环境以及用于渲染非原生组件的环境是各不相同的,具体区别如下:

运行环境逻辑层渲染层

Android

V8

自研Xweb引擎,基于Mobile Chrome

IOS

JSCore

WKWebView

开发工具

NW.js

Chromium Webview

PC端(window)

Chrome内核

Chrome内核

Mac

JSCore

WKWebView

不知道你看见这儿有没有形成疑惑呢? (T_T)

呃......我讲到这儿倒是对前面一句话有点疑惑的,就是 “逻辑层运行在 JSCore 中”,具体看法解释就置于下边的 JSCore 目录中了,可以在下边查看。

小程序整体构架

通过前面的内容,你应当大致了解小程序诞生的情况和所处的环境了,下面我们就来谈谈小程序的整体设计架构情况。

整个小程序系统架构分成两个部份:视视口(WebView) 和 逻辑层(App Service),这两个部份分别由两个独立线程管理。

视图层和逻辑层之间的沟通则须要利用 系统层(WeixinJsBridage) 进行通讯,逻辑层把数据变化通知到视图层,触发视图层页面更新,视视口把触发的风波通知到逻辑层进行业务逻辑处理。

页面渲染大致过程为:我们把项目进行编译会把 WXML 转化成对应的 JS 对象(Virtual DOM),在逻辑层发生数据变化的时侯,我们会通过 setData() 方法把数据从逻辑层传递到视图层,视图层在接收到数据后,会内部进行差别对比,把差别应用在原先的 Dom 树上,再正确的渲染出 UI 界面,完成页面的渲染过程。

通过前面的剖析,你是否能理解开头放置的构架图了呢? (-^〇^-)

上面的剖析还提到到了一个 系统层(WeixinJsBridage),一般简称为 JSBridge,它起到了一个中间桥梁的作用,非常重要。它除了让视图层与逻辑层两个单独线程能进行通讯,而且也架起下层开发与系统底层功能(Native)的桥梁,使得小程序可以通过调用 API 使用原生功能,且部份组件用原生组件实现,从而有良好体验。

逻辑层还有一个重要的操作,发送网路恳求,它也是经由 系统层 转发的。

讲到这儿,希望你对小程序的整体构架有一定认识了,下面我们开始就讲一下小程序内部的一些机制情况了。

运行机制

架构解读_微信的架构师_微信小程序 遮蔽层

小程序启动运行两种情况:

需要注意:

1.小程序没有重启的概念。

2.当小程序步入后台,客户端会维持一段时间的运行状态,超过一定时间后会被陌陌主动销毁。

3.短时间内收到系统两次以上显存警告,也会对小程序进行销毁,这也就为何一旦页面内存溢出,页面会奔溃的本质缘由了。

更新机制

小程序 冷启动 时假如发觉有新版本,将会异步下载新版本的包,并同时会先用客户端本地的旧包进行启动,等上次冷启动才能应用上。如果须要马上应用最新版本,可以用 wx.getUpdateManager API 进行处理。

const updateManager = wx.getUpdateManager()
updateManager.onCheckForUpdate(function (res) {
  // 请求完新版本信息的回调
  console.log(res.hasUpdate)
})
updateManager.onUpdateReady(function () {
  wx.showModal({
    title: '更新提示',
    content: '新版本已经准备好,是否重启应用?',
    success(res) {
      if (res.confirm) {
        // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
        updateManager.applyUpdate()
      }
    }
  })
})
updateManager.onUpdateFailed(function () {
  // 新版本下载失败
})
复制代码

数据通讯机制

前面我们讲过小程序是基于双线程的,那就意味着任何在视图层和逻辑层之间的数据传递都是线程间的通讯,也就是会有一定的延时。这不像传统Web一样,当页面要更新时调用相关API能够同步渲染下来,在小程序构架上面,这一切成了异步操作。

异步会促使各部份的运行时序显得复杂一些。比如在渲染首屏的时侯,逻辑层与渲染层会同时开始初始化工作,但是渲染层须要有逻辑层的数据能够把界面渲染下来,如果渲染层初始化工作较快完成,就要等逻辑层的指令能够进行下一步工作。因此逻辑层与渲染层须要有一定的机制保证时序正确,在每位小程序页面的生命周期中,存在着若干次页面数据通讯。

知道视图层与逻辑层的具体通讯过程后,我们也稍稍了解一下视图层和逻辑层的数据传输大致是怎样的,我们晓得这三者通讯是依靠了系统层的作用,而实际上是通过两侧提供的 evaluateJavascript 所实现的。即用户传输的数据,需要将其转换为字符串方式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的方式传递到两侧独立环境。

关于evaluateJavascript:

Native 调用 JS, 一般就是直接 JS 代码字符串,有点类似我们调用 JS 中的 eval 去执行一串代码。它通常有 loadUrl、evaluateJavascript 等几种方式。

这里就不做过多的介绍了,你只要记住,它是拿来调用执行 JS 字符串,是一种 Native 用来辨识 JS 代码的形式的就行啦。

登录机制

架构解读_微信的架构师_微信小程序 遮蔽层

做过小程序的铁汁们应当对这张图不陌生了:

图中过程主要是为了获得陌陌用户的惟一 openid 与 session_key,之后开发者服务器可以依据用户标示来生成自定义登陆态,用于后续业务逻辑中前前端交互时辨识用户身分。

调用 wx.login() 获取临时登陆账簿 code,并回传到开发者服务器。调用 auth.code2Session 接口,换取用户惟一标示 openid 、用户在微信开放平台账号下的惟一标示 UnionID(若当前小程序已绑定到微信开放平台账号)和会话秘钥 session_key。UnionID 机制说明

UnionID 是陌陌不久前新降低的一个性质,其获取方法和 openid 差不多,作用也差不多,都是指用户惟一标示,但它的范围广一点。

官方解释:如果开发者拥有多个联通应用、网站应用、和公众账号(包括小程序),可通过 UnionID 来分辨用户的唯一性,因为只要是同一个微信开放平台账号下的联通应用、网站应用和公众账号(包括小程序),用户的 UnionID 是惟一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,UnionID是相同的。

不懂?说白了,就是把小程序绑定 微信开放平台账号 后,可与该账号下绑定的的其他联通应用、网站应用及公众号打通。例如:同个用户在PC端的扫描登陆、微信公众号开发的页面授权登陆、微信小程序授权登陆,这些场景中都能辨识出是同一个用户,获取到的 UnionID 相同的。

性能问题

通过学习了小程序的构架原理,我们再来用底层构架的眼光来简单剖析一下常见的小程序性能问题是怎样形成的。

频繁调用setData()

频繁调用 setData(),这个问题相信已然是很常见的,比如在定时器中调用、在窃听页面滚动的钩子中调用,这些场景很容易都会造成小程序的性能问题,容易出现页面卡顿、页面数据更新不及时的情况。

前面在 数据通讯机制 中我们讲过小程序是基于双线程的,那就意味着任何在视图层和逻辑层之间的数据传递都是线程间的通讯,频繁的去调用 setData(),会促使线程之间仍然处于繁忙状态,逻辑层通知到视视口历时都会上升,视图层收到消息的时侯可能早已距离发出的时间超过一定时间了,渲染页面就不够及时了。

庞大的数据量去调用setData()

还是在上面的 数据通讯机制 中,我们说过传输的数据须要转换成转换为字符串的方式传递,且通过 JS 脚本的方式去执行,当数据量大时,执行脚本的编译执行时间也会下降,占用线程。

页面复杂繁杂的DOM结构

当一个页面 DOM 结构复杂而且十分多的时侯,这必将带来页面显示不及时,页面卡顿,甚至可能会出现页面奔溃的情况,这其中的诱因可想而知,是过分 DOM 绘制、计算都是须要时间的,这将促使线程过渡的工作,带来客户端显存占用上升,从而触发系统回收小程序页面。

JSCore

上面我提及说,对 “逻辑层运行在 JSCore 中” 这句话有点疑惑,是由于我在听到表格中列出的逻辑层运行的环境应当是按系统环境分辨的才对,那这句话是不是就太扼要了?还是说这句话就是指 IOS 的情况呢?因为是官方文档写的话语,所以我没有直接就否决是弄错了,或者单指IOS 的情况。

经过一翻核实,证实虽然这句话是没有问题的,要找寻结果的过程,我们须要写了解一下浏览器的大致情况:

浏览器中最核心的部份则是浏览器内核,每个浏览器都有其各自的内核,而对联通领域影响最深的则当属 WebKit。

WebKit 就是一个页面渲染以及逻辑处理引擎,HTML/CSS/JavaScript 经过它的处理,成为可见且可操作的Web页面。

WebKit 由多个重要模块组成,整体结构如下图:

WebKit 由四个部份组成,分别是:

我们来重点来关注 JSCore 部分,JSCore 是 WebKit 默认内嵌的JS引擎,之所以说是默认内嵌,是因为好多基于 WebKit 分支开发的浏览器引擎都开发了自家的JS引擎,其中最出名的就是 Chrome的V8 引擎。

V8 引擎,相信后端的小伙伴应当不会很陌生了,既然它是基于 WebKit 的,那底层默认也是内嵌 JSCore 的,而 Android 的逻辑层是运行在 V8 上的。

而 IOS 的浏览器引擎则是 WebKit,内部则就是 JSCore。

最后 开发工具 的逻辑层是运行在 NW.js, 上它的官网,看到如何一段话:

我相信它应当也和 WebKit 扯上关系了。

到此这个问题就有了一定认识了,小编就没有继续深入下去了,终结吧。(-^〇^-)

至此,本篇文章就写完啦,撒花撒花。

希望本文对你有所帮助,如有任何疑惑,期待你的留言哦。

微信小程序 遮蔽层
上一篇:易企秀:场景添加音乐指南 下一篇:没有了
相关文章