您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > 小程序

从微信小程序开发者工具源码看小程序架构设计实现原理

时间:2019-07-30 11:32:14  来源:  作者:

使用微信小程序开发已经很长时间了,对小程序开发已经相当熟练了;但是作为一名对技术有追求的前端开发,仅仅熟练掌握小程序的开发感觉还是不够的,我们应该更进一步的去理解其背后实现的原理以及对应的考量,这可能会解释我们在开发过程中遇到的一些疑惑,比如为啥小程序不能操作dom、小程序是web技术渲染还是native技术渲染等等,另一方面对于我们个人成长也是有帮组的。

首先声明下,文章查看小程序开发者工具源码的方法仅限学习使用。

本文将从以下几个方面来说一下小程序的实现原理

  • 如何查看小程序开发者工具源码
  • 小程序架构设计
  • 1、小程序渲染是在同一个线程吗?双线程机制
  • 2、小程序是web渲染吗?界面渲染机制
  • 3、小程序是用web的html标签渲染吗?Exparser组件框架
  • 4、小程序可以操作dom吗?数据驱动

如何查看小程序开发者工具源码

下面我们通过微信小程序开发者工具的源码来说说小程序的底层实现原理。以开发者工具版本号State v1.02.1904090的源码来窥探小程序的实现思路。如何查看微信源码,对于mac用户而言,查看微信小程序开发者工具的包内容,然后进入Contents/Resources/App.nw/js/core/index.js,注释掉如下代码就可以查看开发者工具渲染后的代码。

// 打开 inspect 窗口
 if (nw.App.argv.indexOf('inspect') !== -1) {
 tools.openInspectWin()
 }

然后重启小程序开发者工具,就出现如下左侧页面,点击其中一个页面就能看到view层的dom结构,如下图右侧。

从微信小程序开发者工具源码看小程序架构设计实现原理

 


从微信小程序开发者工具源码看小程序架构设计实现原理

 

小程序架构设计

小程序的架构设计与web技术还是有一定的差别,其吸取了web技术的一些优势,同时也摒弃web技术中体验等不好的地方。下面通过问题的形式来说说小程序架构中的一些设计点。

1、小程序渲染是在同一个线程吗?双线程机制

开发过小程序的都知道,小程序是双线程设计,即视图渲染与业务逻辑分别在运行在不同的线程中。这个设计主要是解决web技术中的一个痛点:

web页面开发渲染线程和脚本线程是互斥的,长时间的脚本运行可能会导致页面失去响应或者白屏,体验糟糕。

小程序为了更好体验,将页面的渲染线程和脚本线程分开设计在不同线程中执行,具体实现:

  • 视图view层在webview中渲染,一个页面对应一个webview
  • 业务逻辑Appservice层运行在同一个JSCore线程中,具体IOSJAVAScriptCore,Android是X5 JSCore,开发者工具是webview中;

这样解决了长时间的脚本阻塞页面渲染的情况,但是也带来一些新的问题:

  • 天生的延迟,线程间要通信
  • 业务逻辑层因为运行在JSCore中无法访问DOM和BOM的api;

开发者工具使用webview加载业务逻辑层的代码,虽然依赖的环境有DOM和BOM api,为了保持一致;小程序对所有的模块进行了局部化处理使其不能访问这些api。这样双线程通过native,开发者工具通过后台websocket服务来进行二者消息中转。具体可以参考官网图:

从微信小程序开发者工具源码看小程序架构设计实现原理

 

2、小程序是web渲染吗?界面渲染机制

页面渲染的方式主要有三种:

  • 纯web渲染
  • 纯native原生渲染
  • Hybrid渲染,即web和native渲染结合

因为小程序的宿主环境是微信,不太可能使用纯native渲染,否则所有小程序需要跟微信一起编码发版。采用纯web渲染貌似是可行的,支持快速在线更新,通过加装最新资源到本地即可渲染;但是纯web渲染在一些有复杂交互的页面上可能会面临一些性能问题,这是因为在web技术中,UI渲染跟 JavaScript 的脚本执行都在一个单线程中执行,这就容易导致一些逻辑任务抢占UI渲染的资源。所以小程序采用Hybrid方式渲染,用官网的描述如下:

界面主要由成熟的 Web 技术渲染,辅之以大量的接口提供丰富的客户端原生能力。同时,每个小程序页面都是用不同的WebView去渲染,这样可以提供更好的交互体验,更贴近原生体验,也避免了单个WebView的任务过于繁重。

既然采用Hybrid方式渲染,那么页面的渲染可能会用到原生native来渲染,什么情况会用到原生渲染呢?

答案是使用到小程序提供的mapvideocanvastextarea等组件,页面中原生渲染的渲染原理可以参考官网原生组件。但是在小程序开发者工具中原生组件是使用html标签来模拟实现的。具体可以看下一节的map组件渲染结果。

3、小程序是用web的html标签渲染吗?Exparser组件框架

上面说到小程序主要由成熟的web技术渲染,能否直接使用html提供的标签如div、table等组织页面呢,答案不可以。主要考量:

  • 管控与安全:web技术可以通过脚本获取修改页面敏感内容或者随意跳转其它页面
  • 能力有限,会限制小程序的表现形式
  • 标签众多,增加理解成本

所以,小程序不能直接使用html标签渲染页面,其提供了10多个内置组件来收敛web标签,并且提供一个JavaScript沙箱环境来避免js访问任何浏览器api。

既然小程序不能直接使用html标签来渲染页面,那它提供的如viewcover-view等内置组件是否意味着最终都转换为html提供的内置标签来渲染呢?答案当不是。我们来看如下代码:

<view class="map-container">
 <map latitude='39.9088230000' style="height: 100%; width:100%;" longitude='116.3974700000' scale='16' id="id" bindregionchange="onRegionChange"></map>
 <view catchtap="onTap">test</view>
</view>

上面代码在开发者工具中最终渲染元素如下图:

从微信小程序开发者工具源码看小程序架构设计实现原理

 

可以看出,小程序提供的组件并没有最终转换为为html对应的标签来渲染,而是使用自定义的元素来渲染。这些内置组件都是由Exparser框架负责管理,它内置在小程序基础库中,为小程序的各种组件提供基础的支持。

Exparser框架基于Shadow DOM模型,模型上与WebComponents的ShadowDOM高度相似,具体可以参考官网组件系统。内置组件创建方式如下:

从微信小程序开发者工具源码看小程序架构设计实现原理

 

4、小程序可以操作dom吗?数据驱动

小程序为了管控与安全,提供一个JavaScript沙箱环境来运行JavaScript代码,js代码不能访问任何浏览器相关的接口,那就意味着js是不能操作dom和bom的,否则可能报错。小程序实现沙箱环境呢?即通过将业务逻辑封装到一个局部环境中,局部环境修改dom和bom的相关api指向。具体封装如下:

define("pages/xx/xxx.js", function(require, module, exports, window,document,frames,self,location,navigator,localStorage,history,Caches,screen,alert,confirm,prompt,fetch,XMLHttpRequest,WebSocket,webkit,WeixinJSCore,Reporter,print,URL,DOMParser,upload,preview,build,showDecryptedInfo,syncMessage,checkProxy,showSystemInfo,openVendor,openToolsLog,showRequestInfo,help,showDebugInfoTable,closeDebug,showDebugInfo,__global,WeixinJSBridge){ 
 'use strict';
 // your code here
}

这里的define是小程序底层实现模块化的方法之一,还有一个是require方法;通过define来定义一个模块,require来引用一个define定义的模块。从上面小程序对业务模块代码的封装可以看出:

  • define定义的模块对传递了跟浏览器相关的接口同名的API,如window、document、localStroage等等
  • require在引用模块时只传递require、module、exports三个参数,那么其他参数值就为undefined,不能在业务代码中访问这些接口

可以看看require定义的源码:

从微信小程序开发者工具源码看小程序架构设计实现原理

 

在实际的微信环境,业务逻辑层运行在JSCore中,其没有浏览器相关的信息,访问dom无从谈起;但是小程序开发者工具使用webview来运行业务逻辑代码,它有dom相关接口;所以通过上面沙箱环境来统一使js无法操作dom。

业务代码无法访问dom,怎么实现页面动态更新呢?

答案就是采用类vue这种MVVM框架的数据驱动思想,即让视图状态和视图绑定在一起,状态变更时,视图也能自动变更,这样就不用直接操作dom。

视图的动态更新具体是采用virtual dom技术实现,virtual DOM相信大家都已有了解,大概是这么个过程:

用JS对象模拟DOM树 -> 比较两棵虚拟DOM树的差异 -> 把差异应用到真正的DOM树上。

下面以官网的一幅图来说视图动态更新的过程:

 // wxml
 <view>{{msg}}</view>
// js
data: {
 msg: 'Hello World'
}
从微信小程序开发者工具源码看小程序架构设计实现原理

 



Tags:小程序架构   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
微信小程序包含下面四种文件: js json 配置文件 wxml 小程序专用 xml 文件 wxss 小程序专用 css 文件<view> <text class="window">{{ text }}</text></view> Page({ data:{...【详细内容】
2019-09-10  Tags: 小程序架构  点击:(132)  评论:(0)  加入收藏
使用微信小程序开发已经很长时间了,对小程序开发已经相当熟练了;但是作为一名对技术有追求的前端开发,仅仅熟练掌握小程序的开发感觉还是不够的,我们应该更进一步的去理解其背后...【详细内容】
2019-07-30  Tags: 小程序架构  点击:(330)  评论:(0)  加入收藏
▌简易百科推荐
一、项目背景随着小程序在用户规模和商业化上取得的极大成功,各大平台都推出了自己的小程序。然而这些平台的小程序开发在语法上又不尽相同,不同平台小程序代码的维护需要投入...【详细内容】
2021-11-05  携程技术    Tags:小程序   点击:(65)  评论:(0)  加入收藏
作者:灰灰来源:JS每日一题 一、背景传统的web开发实现登陆功能,一般的做法是输入账号密码、或者输入手机号及短信验证码进行登录服务端校验用户信息通过之后,下发一个代表登录态...【详细内容】
2021-10-29  Nodejs开发    Tags:微信小程序   点击:(43)  评论:(0)  加入收藏
总结列举微信小程序开放能力清单 硬件能力 蓝牙 NFC读写 连接WIFI设备 开放能力 ...【详细内容】
2021-09-27  软件开发分享    Tags:微信小程序   点击:(60)  评论:(0)  加入收藏
核心商城(CoreShop)介绍核心小程序商城系统(CoreShop) 是基于 Asp.Net 5.0、Uni-App开发、支持可视化布局的小程序商城系统;前后端分离,支持分布式部署,跨平台运行;拥有分销、代理、...【详细内容】
2021-07-20  码农也有梦想    Tags:小程序商城   点击:(115)  评论:(0)  加入收藏
介绍Vue3发布已经有一段时间了,从目前来看,其生态还算可以,也已经有了各种组件库给予了支持,但是不管是Vue3还是Vue2都无法直接用来开发小程序,因此国内一些技术团队针对Vue开发...【详细内容】
2021-07-13  爱分享Coder    Tags:小程序   点击:(204)  评论:(0)  加入收藏
首先明确几个概念1. W3C:指万维网联盟(World Wide Web Consortium),是一个国际的标准的制定机构。2. H5(HTML5,HyperText Markup Language 5的缩写),HTML5 是由W3C制定的新HTML标...【详细内容】
2021-07-06  畅游零和一的海洋    Tags:微信小程序   点击:(153)  评论:(0)  加入收藏
在开发微信公众号时,需要不时请求URL和数据封装。为了不做重复的工作。提取公共部分进行封装。产生了相应的公众类。今天先来写下请求类,代码如下:public class HttpRequestP...【详细内容】
2021-06-16  java浮萍  今日头条  Tags:公共类   点击:(134)  评论:(0)  加入收藏
小程序上线后,改版了很多次,包括一些 Api 接口也有改动。如果你学习一个很久之前的小程序项目是没有意义的,本文推荐的小程序都是最近有更新的。相信在你学习、部署的过程中,不...【详细内容】
2021-06-08    程序猿久一  Tags:微信小程序   点击:(207)  评论:(0)  加入收藏
自从2019年微信公开课Pro在微信之夜演示《跳一跳》以来,微信小游戏已经不知不觉走过的三年,这三年中我们可以明显看到微信对小游戏的扶持,对于微信开发者来说,微信小游戏开发以...【详细内容】
2021-05-25  开课吧科科  今日头条  Tags:微信小游戏   点击:(212)  评论:(0)  加入收藏
学习编程从hello world开始。学习微信小程序开发首先要安装一个微信开发者工具,官网上免费下载童叟无欺,下载完傻瓜式安装即可。 双击微信开发者工具,然后选择小程序,然后点击...【详细内容】
2021-05-12  程序员fearlazy  fearlazy  Tags:微信小程序   点击:(268)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条