小程序底层架构

小程序底层架构

与浏览器对比

以微信小程序为例,与浏览器中的对应关系:

  • js 开发逻辑代码 -> js -> v8
  • wxss (多了rpx单位)控制样式 -> css -> 浏览器渲染器
  • wxml xml语言 控制渲染层展示 -> html -> 浏览器渲染器 -> dom

浏览器

  • 单线程 存在阻塞

小程序

  • 双线程架构
    • js 逻辑层
    • wxml、wxss 视图层
  • JSBridge 通信(可以实现相机、扫码)

《小程序底层架构》

微信小程序初级架构

  • 所有的逻辑代码会打成一份,一个小程序只有一个逻辑层,包含所有页面逻辑 js
  • 视图层(渲染层)一个页面对应一个 Webview,小程序中页面栈最多十层。
    • webview 用来渲染 wxml 和 wxss
      • 在本地开发工具,直接用 iframe
      • 在客户端,用真的 webview

《小程序底层架构》

小程序运行环境

运行环境逻辑层渲染层
iOSJavaScriptCoreWKWebView
安卓V8chromium定制内核
小程序开发者工具NWJSChrome WebView

nw:node(io/网络/资源处理/js)-webkit(html/css)

底层实现(基础库)

基础库:对底层运行时的封装,提供事件、数据变更、通信、基础函数

底层需要实现的功能:

  1. 视图层和逻辑层的编译
  2. 逻辑层和视图层之间的通信

查看基础库

微信开发工具 -> 执行 openVendor() -> 打开基础库

可以看到两个可执行文件:

  • wcc: Wechat WXML Complier wxml 编译器
  • wcsc: Wechat WXSS Compiler wxss 编译器

和基础库 xxx.wxvpkg

基础库内容

基础库用 wxappUnpacker 反编译,得到:

  1. WAWebview.js 视图层引擎
  • Foundation 基础模块
    • 提供环境变量 env、isService、isWebview、eventEmit、jsbridge、ready监听 配置
  • WeixinJSBridge 消息通信机制
  • NativeBuffer 转换数据格式
  • Reporter 日志系统
  • exparser 组件系统 Shadow DOM、WebComponent 规范、wx-element
    • 提供友好交互的组件 picker、slider、swiper 等
    • 承接原生组件 video、canvas 等
    • 事件系统
    • 注册组件 window.exparser.registerElement()
  • __virtualDOM__
  1. WAService.js 逻辑层引擎
  • Foundation 基础模块
    • 提供环境变量 env、isService、isWebview、eventEmit、jsbridge、ready监听 配置
  • WeixinJSBridge 消息通信机制
  • 路由管理
  • 生命周期管理
  • __subContextEngine: App、Page、Component getApp
  • __virtualDOM__:提供 querySelector 方法

编译器

编译 wxml

wcc(Wechat WXML Complier) wxml 编译器 -> js
初始化时:

  1. 编译生成 js,执行 js 生成构建虚拟 dom 的函数
  2. 数据传递给 构建虚拟 dom 的函数,生成 vdom 描述
  3. vdom 描述经过组件系统 exparser 的解析构建真实 dom

数据变更时:

  1. 执行上面 2、3 步
  2. dom diff 对比、渲染

wxml 经过 WAWebview 编译成 js,js + 虚拟 dom -> wxml描述文件,交给组件系统 exparser,去渲染更新

编译 wxss

wcsc(Wechat WXSS Compiler) wxss 编译器 -> js

  1. 处理单位 rpx,根据手机物理像素及分辨率来计算实际应该为多少
  2. 生成新的 style,插入

初始化流程

渲染层

控制台输入 document.getElementsByTag('webview')[0] 得到渲染层。

  1. 初始化 __webviewId__(标识当前是哪个 webview )、__wxAppCode__
  2. wcc 生成渲染器方法的代码(wxml -> js)
  3. 加载执行 wcsc 打包出来的代码(js代码),生成 css
  4. 初始化页面配置
  5. $gwx -> generateFunc(渲染器,执行生成虚拟 Dom),需要数据
  6. 触发自定义事件,传递渲染器函数
     var generateFunc = $gwx(decodeName)
     if(generateFunc) { 
       var CE = window.CustomEvent
       document.dispatchEvent(new CE('generateFuncReady', { 
         detail: { 
           generateFunc: generateFunc
         }
       }))
     } else { 
       ...
     }
    
  7. 基础库 WAWebview 中监听了 generateFuncReady 事件,该事件中会触发 WexinJSBridge,通知逻辑层渲染层已加载完成,等待逻辑层传数据。逻辑层执行完之后执行 generateFunc 回调,并拿到逻辑层传来的数据,生成虚拟 dom
  8. 虚拟 dom 描述经过组件系统 exparser 的解析构建真实 dom

逻辑层

控制台输入 document 得到逻辑层。

  1. 初始化配置项(页面配置项、全局配置项)
  2. 加载逻辑层基础库(维护了 Page、App、Component、wx.getSetting、wx.scanCode 等)
  3. 维护一个逻辑层渲染器,加载逻辑代码(开发者写的代码)
  4. 构建 __wxAppCode__,保存所有页面的配置和渲染器方法

整体流程图

《小程序底层架构》

    原文作者:張猴子
    原文地址: https://blog.csdn.net/qq_42532128/article/details/113726964
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞