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

微信小程序架构原理

时间:2019-09-10 10:13:50  来源:  作者:

微信小程序包含下面四种文件:

  • js
  • json 配置文件
  • wxml 小程序专用 xml 文件
  • wxss 小程序专用 css 文件
<view>
 <text class="window">{{ text }}</text>
</view> 
Page({
 data:{
 text:"这是一个页面"
 },
 onLoad:function(options){
 // 页面初始化 options为页面跳转所带来的参数
 },
 // ........
}) 

微信小程序只能通过其 mvvm 的模板语法来动态改变页面,本身 js 并不支持 BOM 和 DOM 操作。

从开发工具看微信小程序架构

mac 端直接解压应用 发现 App.nw 文件夹,即开发工具源码。可以知道该项目由 nw.js 编写; 在 package.json 文件下找到应用入口:app/html/index.html。入口 js 为 dist/app.js 我们可以看到整个编辑器的大致逻辑。

但我们关心的是构建过程,在 weapp 文件夹下存在 build.js 文件。没有找到有用的信息,只看到了 upload 模块,包括对大小限制,上传包命名。

为此怀疑,微信小程序本身和 RN 类似。是在服务端打包成 native 语言的。但是通过 Android 边框测试发现,微信小程序根本不是 native 原生内容。

原生界面效果:

微信小程序架构原理

 

编译过程

继续在 trans 文件夹下发现了编译模板。

  • transWxmlToJs wxml 转 js
  • transWxssToCss wxss 转 css
  • transConfigToPf 模板页配置
  • transWxmlToHtml wxml 转 html
  • transManager 管理器

用到的内容:

  • 发现用到了一个模板:app.nw/app/dist/weapp/tpl/pageFrameTpl.js, app.mw/app.dist.weapp/tpl/appserviceTpl.js
  • wcc 可执行程序,wcc 用于转转 wxml 中的自定义 tag 为 virtual_dom
  • wcsc 可执行程序,用于将 wxss 转为 view 模块使用的 css 代码,使用方式为 wcsc xxx.wxss

在模板中,我们发现使用了 WAWebview.js 文件,WAService.js文件。 在 transWxmlToJs 中我们发现一段 generateFuncReady 事件的函数。对比注册该事件的函数在 WAWebview.js 中。

我们尝试使用 wcc 对input.xml 文件进行编译。

wcc -d input.xml

生成了一段脚本:

window.__wcc_version__ = 'v0.6vv_20161230_fbi'
var $gwxc
var $gaic = 
$gwx = function (path, global) {
 function _(a, b) {
 b && a.children.push(b);
 }
 ....

通过代码我们发现,调用 $gwx 函数会再生成一个有返回值的函数(前提是 path 填写正确);于是我们执行如下代码:

$gwx("input.xml")("test")

得出如下内容:

{
 "tag": "wx-page",
 "children": [
 {
 "tag": "wx-view",
 "attr": {
 "class": "section"
 },
 "children": [
 {
 "tag": "wx-input",
 "attr": {
 "autoFocus": true,
 "placeholder": "这是一个可以自动聚焦的input"
 },
 "children": []
 }
 ]
 }
 ]
} 

这应该是一个类似 Virtual dom 的对象,交给了 WAWebivew.js 来渲染,标签名为 wx-view, wx-input。

WAWebview.js

  1. 代码在最一开始提供的是兼容性工具,还有一个 WeixinJSBridge 引入。
  2. 接下来是一个 Reporter 对象,它的作用就是发送错误和性能统计数据给后台。
微信小程序架构原理

 

  1. wx 核心对象,包含了 wx 对象下的 api。但是这里的 api 数量远远少于官方的 api 文档数量。
微信小程序架构原理

 

我们可以在代码里面发现,wx 下注册的 api 最终都会调用 WeixinJSBridge 方法。这个方法应该是在打包的时候端上注入的。我们也可以在 WAServeice.js 中找到该方法的定义。

微信小程序架构原理

 

所以我们得到了一个结论,WAService.js 是编辑器用来接受 wx 方法回调的代码。

  1. wxparser 对象,提供 dom 到 wx element 对象之间的映射操作,提供元素操作管理和事件管理功能。
  2. 之后代码是对 exparser 对象的处理,包括注册 WeixinJSBridge 全局事件,Virtual dom 算法实现,样式注入等。介绍几个组件重要的内容
  • exparser.registerBehavior 注册组件基础行为,供组件继承。
微信小程序架构原理

 

  • exparser.registerElement 为各种内置组件,注册模板,行为,属性,监听器等内容
微信小程序架构原理

 

这里我们观察到,组件:wx-video, wx-canvas, wx-contact-button, wx-map, wx-textarea 等 behaviors 都含有 "wx-native" 属性。这是不是意味着,这类组件都是 native 原生实现的呢。我们打开边框检查,发现这类组件确实都是原生的组件。

微信小程序架构原理

 

综上,微信小程序的界面有部分组件使用原生方式实现的,native 组件层在 WebView 层之上。大部分还是用前端实现的,这样解释了微信小程序的一个bug。

微信官方文档:

微信小程序架构原理

 

 

因为%20scroll-view%20是前端实现,在里面使用%20native%20组件,这样就无法监听滚动了。

WeixinJSBridge

组件是需要数据来渲染的,查看文档我们知道发送请求的%20api%20为%20wx.request;通过上面分析,我们知道%20wx.request%20实际调用的是%20WeixinJSBridge。现在我们看看%20WeixinJSBridge

 

WeixinJSBridge 真正发送处理数据请求的是这段代码;如果当前环境是 IOS, 那么调用 WKWebview 的 window.webkit.messageHandlers.invokeHandler.postMessage。如果所处环境是 android 则调用 WeixinJSCore.invokeHandler (调用的时候,默认会带上当前 webviewID)。

WAService.js

在对 WeixinJSBridge.js 分析中,我们并没有发现前端的通讯功能,路由能力,数据绑定等内容。进一步查看找到了一个 WAService.js 文件。 查看 WAService.js 文件源码:

  1. 在代码最开始,跟 WAWebview.js 一样的 WeixinJSBridge 兼容模块
  2. 然后是跟 WAWebview.js 一样的 Reporter 模块。
  3. 比 WAWebview.js 中 wx 功能更为丰富 wx 接口模块。(剩余部分 wx api 都在这里)
  4. appServiceEngine 模块,提供 Page,App,GetApp 接口
  5. 为 window 对象添加 AMD 接口 require define

综上,WAService.js 主要实现的功能:

  • App( ) 小程序的入口;Page( ) 页面的入口
  • wx API;
  • 页面有的作用域,提供模块化能力
  • 数据绑定、事件分发、生命周期管理、路由管理

到这里我们得出结论,小程序的架构方案:

微信小程序架构原理

 

整个小程序由两个 webview 组成,代码分为 UI 层和逻辑层。UI 层运行在第一个 WebView 当中,执行 DOM 操作和交互事件的响应,里面是 WAWebview.js 代码及编译后的内容。逻辑层执行在(第二个webview 中)独立的 JS 引擎中(iOS:JAVAScriptCore, android:X5 JS解析器;统称 JSCore;开发工具中,nwjs Chrome 内核),WAService.js 代码和业务逻辑。

当我们对 view 层进行事件操作后,会通过 WeixinJSBridge 将数据传递到 Native 系统层。Native 系统层决定是否要用 native 处理,然后丢给 逻辑层进行用户的逻辑代码处理。逻辑层处理完毕后会将数据通过 WeixinJSBridge 返给 View 层。View 渲染更新视图。

架构的讨论

微信的这种架构,对逻辑和UI进行了完全隔离,小程序逻辑和UI完全运行在2个独立的Webview里面来处理。那么这么做的好处是啥?总感觉更加麻烦了。除了小程序外,还有人采用这种架构设计么?

在网上搜索了一下,目前使用这种架构的项目还真有一个:去哪儿最新的 YIS 框架

YIS 采取了类似小程序的架构,分为逻辑层和UI层。UI 层运行在 WebView 中,而逻辑层运行在独立的 JS 引擎中。相应地,整个应用的代码,也分为两个大的部分,一部分运行在 WebView 中,一部分运行在JS引擎中。JS引擎计算DOM结构输出给WebView,WebView转发用户的点击事件给JS引擎。

该项目做法和小程序十分类似,唯一缺少的就是没有 native 的组件吧。然而官方文档上也没有任何介绍,为什么要这么做,只是说更流畅了。

一些看法

传统 web 页面显示需要经历一下几个步骤:

  1. webview 初始化
  2. 加载 HTML, CSS, JS
  3. 编译 JS
  4. Render 计算
  5. DOM Path

而利用小程序架构后,我们就可以将上述过程拆解成两部分并行执行: webview 部分:

  1. webview 初始化
  2. 加载 HTML,CSS, JS (经过拆分后,体积大幅度减小)
  3. 编译 JS
  4. 等待页面需要的数据
  5. 反序列化数据
  6. 执行 Patch
  7. 渲染页面
  8. 等待更多消息

jscore 部分:

  1. 初始化
  2. 加载框架 js 代码
  3. 编译 js
  4. 加载业务逻辑 js 代码
  5. 编译 js
  6. 计算首屏虚拟 DOM 结构
  7. 序列化数据,传输
  8. 等待 webview 消息,或者 Native 消息

这样渲染进程和逻辑进程分离,并行处理:加速首屏渲染速度;避免单线程模型下,js 运算时间过长,UI 出现卡顿。 完全采用数据驱动的方式,不能直接操作 DOM,利用定制开发规范的方式避免低质量的代码的出现。

当然这种架构方案也有一定的缺点:

  1. 不能灵活操作 DOM,无法实现较为复杂的效果
  2. 部分和 NA 相关的视图有使用限制,如微信的 scrollView 内不能有 textarea。
  3. 页面大小、打开页面数量都受到限制
  4. 需要单独开发适配,不能复用现有代码资源。
  5. 在 jscore 中JS 体积比较大的情况下,其初始化时间会产生影响。
  6. 传输数据中,序列化和反序列化耗时需要考虑

希望本文能帮助到您!

点赞+转发,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓-_-)

关注 {我},享受文章首发体验!

每周重点攻克一个前端技术难点。更多精彩前端内容私信 我 回复“教程”

原文链接:http://eux.baidu.com/blog/fe/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%9E%B6%E6%9E%84%E5%8E%9F%E7%90%86

作者:田光宇



Tags:微信小程序   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
微信小程序“无障碍急救平台”日前上线,解决听障人士120急救呼叫难题。听障人士在日常生活、工作中常有信息缺失、沟通不良的困难。如果自身或身边人突发急症,则需要依靠他人...【详细内容】
2021-12-15  Tags: 微信小程序  点击:(10)  评论:(0)  加入收藏
现如今卖东西的渠道是越来越多,如今在微信小程序也能开店卖东西了,有的小伙伴想在小程序上卖东西但不知道该怎么做,下面就来讲讲微信小程序如何做店铺,利用微信小程序!但凡得到公...【详细内容】
2021-11-03  Tags: 微信小程序  点击:(32)  评论:(0)  加入收藏
作者:灰灰来源:JS每日一题 一、背景传统的web开发实现登陆功能,一般的做法是输入账号密码、或者输入手机号及短信验证码进行登录服务端校验用户信息通过之后,下发一个代表登录态...【详细内容】
2021-10-29  Tags: 微信小程序  点击:(43)  评论:(0)  加入收藏
一、微信服务号主要偏于服务交互(类似银行,114,提供服务查询),认证前后都是每个月可群发4条消息(不适用于个人)二、微信订阅号主要偏于为用户传达资讯(类似报纸杂志),认证前后都是每天...【详细内容】
2021-10-22  Tags: 微信小程序  点击:(82)  评论:(0)  加入收藏
总结列举微信小程序开放能力清单 硬件能力 蓝牙 NFC读写 连接WIFI设备 开放能力 ...【详细内容】
2021-09-27  Tags: 微信小程序  点击:(60)  评论:(0)  加入收藏
功能说明脱离公众号下的小程序,单独使用功能特点小程序:是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或者搜一下即可打开应用。也体现了“用...【详细内容】
2021-09-27  Tags: 微信小程序  点击:(46)  评论:(0)  加入收藏
微信小程序不愧是智能时代的宝藏发明,不用下载不占内存,点开就能用。今天介绍这7个小程序,个个都拥有超实用的功能,用了就知道有多香! 1.腾讯文档腾讯出品的在线文档编辑器,提供在...【详细内容】
2021-08-27  Tags: 微信小程序  点击:(101)  评论:(0)  加入收藏
微信上有很多好用的小程序,虽然不是很多人知道,但却很强大。这里就来分享8款相见恨晚的微信小程序,可以让手机更好用,还不知道的话,未免有点太可惜了,一起来看看吧。 1、专去水印...【详细内容】
2021-07-28  Tags: 微信小程序  点击:(101)  评论:(0)  加入收藏
微信小程序的出现让手机内存不再高负荷,同时也出现了很多实用的小程序例如以下这么几个。1、文章截图文章截图小程序主要实用功能可以通过截图实现保证精度的情况下进行无缝...【详细内容】
2021-07-14  Tags: 微信小程序  点击:(83)  评论:(0)  加入收藏
微信上有很多小程序,比起app更小巧,使用起来更加方便。这里就来为大家分享7个精心挑选的微信小程序,每一个都让人觉得相见恨晚,能让你的手机更好用。 1、群相册服务专属于一个群...【详细内容】
2021-07-13  Tags: 微信小程序  点击:(124)  评论:(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)  加入收藏
最新更新
栏目热门
栏目头条