微信小程序实现原理

微信小程序采用wxmlwxssjavascript进行开发,本质是一个单页应用,所有的页面渲染和事件处理,都在一个页面内进行,但又可以通过微信客户端调用原生的各种接口。微信的架构,是数据驱动视图的MVVM模式,其视图UI和数据是分离的,所有的页面更新,都需要通过对数据的变更来实现。小程序分为两个部分WebviewAppServiceWebview主要用来展现渲染界面,AppService用来处理业务逻辑、数据及接口调用,通过系统层JSBridge实现通信,实现UI的渲染与事件的处理。

目录结构

打包前

Project
   ├── pages
   │   ├── index
   │   │     ├── index.js              // index 逻辑
   │   │     ├── index.json            // index 配置
   │   │     ├── index.wxml            // index 结构
   │   │     └── index.wxss            // index 样式表
   │   └── logs
   │         ├── logs.js               // logs 逻辑
   │         ├── logs.json             // logs 配置
   │         ├── logs.wxml             // logs 结构
   │         └── logs.wxss             // logs 样式表
   ├── app.js                          // 逻辑
   ├── app.json                        // 公共配置
   ├── app.wxss                        // 公共样式表
   ├── project.config.json             // 项目配置
   └── sitemap.json                    // 页面收录配置

打包后

Project
   ├── app-config.json                  // 小程序工程全部json配置信息
   ├── app-service.js                   // JS业务逻辑打包到此处
   ├── page-frame.html                  // 视图的模板文件
   └── pages
         ├── index.html                 // index 页面
         └── logs.html                  // logs 页面

架构方案

微信小程序的框架包含两部分View视图层与AppService逻辑层,View层用来渲染页面结构,AppService层用来逻辑处理、数据请求、接口调用,它们在两个进程里运行,具体实现是在两个Webview中运行。
视图层和逻辑层通过系统层的JSBridge进行通信,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理。

-----------------------                           -----------------------
|         View        |                           |      AppService     |
|                     |                           |                     |
|  Page1 Page2 Page3  |                           |      Manager Api    |
-----------------------                           -----------------------
     |           ↑                                     |           ↑
     | Event     | Data                                | Data      | Event
     ↓           |                                     ↓           |
-------------------------------------------------------------------------
|                               JSBridge                                |
|                                                                       |
|                      Native Storage Network ...                       |
-------------------------------------------------------------------------

微信将所有的视图都将加载到一个Webview中,称之为View层。将所有进行逻辑处理的JS代码全部加载到另一个WebView中,称之为AppService层,每个小程序只有一个并且整个生命周期常驻内存。在JSBridge中封装了消息通信以及通过App访问OS能力的实现,对于消息通信通过在不同平台调用相应的方法进行通信,开发环境为window.postMessage, IOS下为WKWebviewwindow.webkit.messageHandlers.invokeHandler.postMessageAndroid下为WeixinJSCore.invokeHandler。在Js引擎方面,Android中使用X5内核,IOS中使用JavaScriptCore引擎,开发工具中使用nwjs Chrome内核。
通过使用View视图层与AppService逻辑层就实现了双线程的小程序运行方案,通过两个线程,可以做到将代码放入沙箱执行,从而做到对于代码执行的安全与管控,当然对于双线程只是一个小程序的解决方案,倘若要在一个App上运行多个小程序,就应该采用多线程方案去执行,不仅是对于性能方面的考虑,也是为了防止小程序之间相互影响。

底层支持

微信小程序开发工具中拥有一些编译支持模板以及小程序底层支持文件。

  • transWxmlToJs: wxmljs
  • transWxssToCss: wxsscss
  • transConfigToPf: 模板页配置
  • transWxmlToHtml: wxmlhtml
  • transManager: 管理器
  • WAConsole.js: 框架JS库,控制台能力
  • WAWebview.js: 框架JS库,提供视图层基础的API能力,主要功能有将消息通信封装为JSBridge消息,日志组件Reporter封装,wx对象下部分渲染视图方面的Api,小程序组件实现和注册,VirtualDOMdiffRender UI的实现,页面事件触发处理
  • WAService.js: 框架JS库,提供逻辑层基础的API能力,主要功能有消息通信封装为JSBridge消息,日志组件Reporter封装,wx对象下面的大部分Api方法,App()小程序入口,Page()页面的入口,getApp等全局方法,数据绑定,事件分发,生命周期管理,路由管理,模块化能力等

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://www.zhihu.com/question/50920642
https://kangzubin.com/wxapp-decompile-1/
https://github.com/berwin/Blog/issues/49
http://eux.baidu.com/blog/fe/微信小程序架构原理
https://cloud.tencent.com/developer/article/1029663