专栏首页腾讯技术工程官方号的专栏微信小程序基础架构浅析

微信小程序基础架构浅析

作者:billgong,腾讯IEG前端开发工程师。

微信小程序,简称小程序,英文 mini program。是一种不需要下载安装即可在微信中使用的应用,用户扫描小程序码或搜索小程序即可打开,触手可及,用完即走,不用关心是否安装太多应用的问题。

小程序技术演进

内部开放微信原生能力

使用 WeixinJSBridge 预览图片

此类 API 最初是提供给腾讯内部一些业务使用,很多外部开发者发现了之后,依葫芦画瓢地使用了,逐渐成为微信中网页开发的事实标准。

JS-SDK 发布

2015 年初,微信发布了一整套网页开发工具包,称之为 JS-SDK,开放了拍摄、录音、语音识别、二维码、地图、支付、分享、卡券等几十个 API。让所有开发者都可以使用到微信的原生能力。

使用 JS-SDK 调用图片预览组件

JS-SDK 解决了移动网页使用微信能力不足的问题,通过暴露微信的接口使得 Web 开发者能够拥有更多的能力,然而在更多的能力之外,JS-SDK 的模式并没有解决使用移动网页遇到的体验不良的问题。

JS-SDK 的不足

用户在访问网页的时候,在浏览器开始显示之前都会有一个白屏的过程,在移动端,受限于设备性能和网络速度,白屏会更加明显。除了白屏,影响 Web 体验的问题还有缺少操作的反馈,主要表现在两个方面:页面切换的生硬和点击的迟滞感。

加载白屏,切换不流畅

此外一些开发者会使用 JS-SDK 做一些,比如假红包,伪造的官方活动等。并利用 JS-SDK 的分享能力变相的去裂变分享到各个群或者朋友圈,由于 JS-SDK 是根据域名来赋予 api 权限的,运营人员封了一个域名后,他们立马用别的域名又继续做坏,要知道注册一个新的域名的成本是很低的。

那么小程序是通过怎样的设计来改进 JS-SDK 的体验和管控上的不足?

小程序双线程架构

具体实现上小程序采用了类 web + 离线包的形式。开发上与 web 类似,门槛较低,开发效率较高。离线下载和页面预渲染功能增强了用户体验,提升了加载速度,解决了 JS-SDK 加载白屏的问题 1。小程序提供了云端更新离线包的功能,可动态更新页面,相对于 app 的更新和发布更为灵活。此外,小程序在离线包的基础上对切换动画进行优化,降低了切换页面导致的迟滞感,缓解了切换不流畅的问题 2。

小程序web+离线包模式

小程序在架构方面最大的特点是采用了双线程的开发模式,隔离了 JS 逻辑和 UI 渲染。小程序的渲染层和逻辑层分别由 2 个线程管理:渲染层的界面使用了 WebView 进行渲染,逻辑层采用 JsCore 线程运行 JS 脚本。

逻辑层:创建一个单独的线程去执行 JavaScript,在这个环境下执行的都是有关小程序业务逻辑的代码; 渲染层:界面渲染相关的任务全都在 WebView 线程里执行,通过逻辑层代码去控制渲染哪些界面。一个小程序存在多个界面,所以渲染层存在多个 WebView 线程; 通信:这两个线程的通信会经由微信客户端(下文中也会采用 Native 来代指微信客户端)做中转,逻辑层发送网络请求也经由 Native 转发,小程序的通信模型下图所示。

小程序双线程架构

JS 逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的 DOM API 和 BOM API,无法操作页面元素,能达到管控的目的,但也限制了开发者的权限:

  1. 不允许开发者把页面跳转到其他在线网页
  2. 不允许开发者直接访问 DOM
  3. 不允许开发者随意使用 window 上的某些未知的可能有危险的 API

这样的逻辑层与 UI 层的隔离,加上小程序的审核和举报机制,使得微信加强对小程序的管控,解决了问题 3。但这也使得开发者无法灵活的进行页面渲染。

小程序页面渲染

上面已经说了逻辑层无法操作 DOM 变更,那小程序是如何进行页面的渲染呢?小程序基于数据驱动的架构模式,基于 Virtual Dom(React 引入,真实 DOM 的一种 JS 描述方式)的概念,业务侧只需要改变数据即可引起界面变化。其中渲染层提供了带有数据绑定语法的 WXML,逻辑层提供了setData 等等 API,开发者需要进行界面变化时,只需要通过在逻辑层执行 setData 把变化的数据通过 Native 层传递到渲染层,小程序会进行 Dom Diff(DOM 结构对比并进行最小化变更的算法)等流程,最后把正确的结果更新在 Dom 树上。

小程序Virtual DOM渲染

完整的通信流程大致如下:

  1. 逻辑层调用宿主环境的 setData 方法。
  2. 逻辑层将待传输数据转换成字符串,并拼接到特定的 JS 脚本,最后将数据传输到渲染层。
  3. 渲染层接收到后,WebView JS 线程会对脚本进行编译,得到待更新数据后进入渲染队列,等待 WebView 线程空闲时进行页面渲染。
  4. WebView 线程开始执行渲染时,待更新数据会合并到视图层保留的原始 data 数据,并将新数据套用在 WXML 片段中得到新的虚拟节点树。经过新虚拟节点树与当前节点树的 diff 对比,将差异部分更新到 UI 视图。同时将新的节点树替换旧节点树,用于下一次重渲染。

小程序方案与 React Native 对比

那么小程序与现有的混合开发技术类型的异同点在哪?尤其是与 React Native 的区别,小程序技术架构为什么没有使用 React Native?

混合开发技术类型

现有的混合开发类型,基于 UI 渲染的分类来看,主要有两类:

  1. 基于 WebView UI 的基础方案。市面上主流,例如微信 JS-SDK,通过 JSBridge 完成 H5 和 Native 的双向通讯,从而赋予 H5 一定的原生能力。
  2. 基于 Native UI 的方案,例如 React-Native、Weex、Flutter 等。在赋予 H5 原生 API 能力的基础上,进一步通过 JSBridge 将 JS 解析成虚拟 DOM 传递到 Native,并使用原生渲染。

小程序也属于类型 1,本次我们主要以类型 2 中的 React Native 作为对比分析。

React Native 技术架构

框架

React Native 框架主要有三层:

  1. JS 层:该层提供了各种供开发者使用的组件以及一些工具库(事件分发等)。
  2. C++层:主要处理 java/OC 与 JS 的通信(JSBridge)以及执行 JavaScript(JS 脚本引擎)。
  3. Native 层(Object C/Java 层):主要包括 UI 渲染器、网络通信等工具库。根据不同操作系统有不同的实现。
UI 渲染

React Native 基于 react 框架(Virtual Dom)来进行 UI 渲染,具体的流程大致如下:

  1. 首先 JS 层通过 JSX 编写的 Virtual Dom 来构建 Component
  2. Native 层将其转成真实 DOM 插入到原生 App 的页面中。
  3. 当有变更,通过 diff 算法生成差异对象
  4. 最终由 Native 层将差异对象应用到原生 App 的页面元素上。
通信

React Native 基于 JSCore 实现 js 与 java/oc 交互,具体流程大致如下:

  1. 把 JSX 代码解析成 javaScript 代码
  2. 读取 JS 文件,并利用利用 JS 脚本引擎执行
  3. 返回一个数组,数组中会描述 OC/Java 对象,描述对象属性和所需要执行的方法,这样就能让这个对象设置属性,并且调用方法。

Reactive Native架构

React Native 优缺点

优势
  1. 原生渲染,性能更好,用户体验较好;
  2. React 生态较好,对前端开发友好;
  3. hybrid 技术跨平台开发,成本及难度低于原生;
  4. 可热更新,能够方便迭代。
劣势
  1. 支持的样式是 CSS 的子集,会满足不了 Web 开发者日渐增长的需求;
  2. 现有能力下还存在的一些不稳定问题,比如性能、Bug 等;
  3. 把渲染工作全都交由客户端原生渲染,会有更接近原生的体验,但实际上一些简单的界面元素使用 Web 技术渲染完全能胜任;
  4. React Native 之前爆出了一个开源协议问题(Facebook BSD+Patents ,大致内容是使用基于 Facebook BSD+Patents 协议的开源项目的开发者,未来要是因为专利问题与 Facebook 产生纠纷,那么 Facebook 将有权停止你使用该开源项目),这对于之后也是存在隐患的。

小程序不选择 React Native 原因

据小程序开发人员告知的原因如下:

  1. React Native 只支持 CSS 的子集,作为一个开放的生态,需要告知开发者哪些 CSS 属性能用,哪些不能用,这样的开发体验较差;(对应上面的劣势 1
  2. React Native 本身存在一些问题,这些依赖 RN 的修复,同时这样就变成太过依赖客户端发版本去解决开发者那边的 Bug,修复周期太长。(对应上面的劣势 2
  3. React Native 前阵子还搞出了一个开源协议问题,来说也是存在隐患的。(对应上面的劣势 4

小程序与 React Native 相同点

  1. 都具有 hybrid 技术的优点:接近原生的体验,跨平台开发
  2. 使用 Web 相关技术框架来编写业务代码,React Native 为 React 框架,小程序为小程序开发框架。
  3. 各自实现了跨语言通讯方案完成 Native(Java/Objective-c/…)端与 JavaScript(小程序中为渲染层和逻辑层)的通讯

小程序与 React Native 不同点

小程序使用浏览器内核 WebView 来渲染界面(小部分原生组件由客户端参与渲染),界面主要由成熟的 Web 技术渲染,辅之大量的接口提供丰富的客户端原生能力,而 React Native 是客户端原生渲染。理论上 React Native 相对于 WebView 的性能更好,但小程序的类 web 开发对开发来说入门相对简单,像是一种开发效率与性能的双刃剑。

小程序开发注意事项

基于上面的架构分析,我们在开发中需要注意是:

  1. 避免使用操作操作 DOM 的 npm 包。由于逻辑层和渲染层隔离,逻辑层无法操作 DOM/BOM API,所以需要使用 DOM/BOM API 相关的 npm 包和库中不可使用。
  2. 避免频繁调用setData。由于setData中的数据不仅需要通过 Native 层传递到渲染层,通过 DOM diff 算法等渲染成最终页面,所以需要尽量减少setData的使用以避免性能问题。
  3. 避免setData传递大量的新数据。数据的传输会经历跨线程传输和脚本编译的过程,当数据量过大,会增加脚本编译的执行时间,占用 WebView JS 线程,从而影响到最终的渲染性能。

参考文档

  1. 小程序官方文档
  2. 小程序原理及 RN 与 Flutter 的对比
  3. React-Native 与小程序的底层框架比较
  4. 多端小程序原理分析
  5. 小程序架构设计(一)
  6. 小程序架构设计(二)

腾讯程序员视频号

最新视频欢迎点赞

本文分享自微信公众号 - 腾讯技术工程(Tencent_TEG),作者:billgong

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-06-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 浅谈微信小程序底层架构

    其实,小程序开发过程中我们面对的是iOS和Android微信客户端和辅助开发的小程序开发者工具。根据官方文档,这三大运行环境也是有所区别的:

    极乐君
  • 微信小程序基础

    小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。也体现了“用完即走”的理念,用户不关心是否安装太多应...

    达达前端
  • 微信小程序基础

    查看官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/

    达达前端
  • 浅析Minium,微信小程序自动化测试框架

    微信发布了小程序的自动化测试框架Minium,提供了多种运行验证方式,其特点:

    小老鼠
  • 微信小程序高级基础

    小程序是什么呢?小程序是一种不需要下载安装就可以使用的应用,它实现了应用"触手可及"的梦想,用户扫一扫或者搜一下就可以打开应用,也体现了龙哥"用完即走"的理念,...

    达达前端
  • 微信小程序开发基础

    查看官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/

    达达前端
  • 微信小程序基础学习

    张小龙:小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。也体现了“用完即走”的理念,用户不用关心是否...

    张世强
  • 微信小程序零基础入门----->结构说明

    小程序框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生App体验服务

    用户5899361
  • 浅析微信小程序的事件机制

    知晓君
  • 微信小程序中的基础语法

    代码演示在微信小程序中的数据绑定思想,wx:if/wx:elif/wx:else,改变数据的方法this.setData({})使用,最终的结果是,让页面的显示...

    天天_哥
  • Basic wechat mini program 基础微信小程序

    vanguard
  • 【阅读清单】有奖内测体验活动

    完成了内测体验的小伙伴,可以填写问卷,活动结束后我们将统一进行审核,审核结束就进行礼品发放。问卷链接:https://wj.qq.com/s2/7433898/...

    云加社区
  • 微信小程序的技术架构特点

    腾讯为微信小程序的工程项目开发了完整的编辑开发、运行调试、打包发布环境,形成了一个完整的IDE。

    用户6117737
  • 一起脱去小程序的外套和内衣:微信小程序架构解析

    微信小程序的公测掀起了学习小程序开发的浪潮,天生跨平台,即用即走、媲美原生体验、完善的文档、高效的开发框架,小程序给开发者带来了很多惊喜。通过这篇文章和大家一起...

    小时光
  • 微信小程序_01程序结构

    注意 AppID 目前个人无法申请,使用企业账号可以申请,我们就选择"无AppID"

    酷走天涯
  • 零基础入门微信小程序开发

    最近一个小游戏“跳一跳”火得不得了,相信即使您自己没有玩过,身边的亲戚朋友也一定玩过。画面大致如下:

    Java编程指南
  • 微信小程序「官方示例代码」浅析【上】

    从某个微信群里,拿到了这个IDE的下载地址,然后就有了这个: ? 根本登不上去,怎么办,怎么办呢? 看代码啊。。。 反正我又没有保密协议,解压缩一看NodeW...

    Phodal
  • 让你见识一下什么叫最完整、最系统的前端学习路线

    随着互联网的深入发展,前端开发工程师已成为市场上极具竞争力的人才。许多学生,包括以前的UI,java,或完全零基础,想学习的前端。那么话不多说,直接上干货,希望...

    用户5827212
  • 微信小程序【浅提WXSS样式】

    WXSS (WeiXin Style Sheets)是一套样式语言,用于描述 WXML 的组件样式。

    BWH_Steven

扫码关注云+社区

领取腾讯云代金券