1

一、原生小程序

1. 小程序底层架构

image

传统的HTML:

解析规则是解析html->遇到js解析执行js->遇到css解析css文件

微信小程序:

文件对应关系
wxml ===> html  dom
wxss ===> css  样式
js   ===> js 逻辑
json ===> json

小程序打包之后的文件:

1、WAService.js 框架JS库。提供逻辑层基础的API能力
2、WAWebview.js 框架JS库,提供视图层基础的API能力
3、WAConsole.js 框架JS库。控制台
4、app-config.js 小程序完整的配置。包括我们通过app.json里的全部配置,综合了默认配置型
5、app-service.js 我们自己的JS代码,全部打包到这个文件
6、page-frame.html 小程序视图的模板文件,全部的页面都使用此载入渲染。且全部的WXML都拆解为JS实现打包到这里
7、pages 全部的页面。这个不是我们之前的wxml文件了,主要是处理WXSS转换,使用js插入到header区域。

微信小程序是双线程架构,分为逻辑层和渲染层,在进行文件解析的时候不会发生阻塞。
逻辑层:
(1)解析js,负责逻辑处理、事件逻辑、动态数据的处理
(2)小程序的所有代码逻辑都包含在同一个逻辑线程(逻辑层是单线程),小程序只有一个APP实例,但是有多个page,小程序编译之后将会把所有page打包至同一个js文件

渲染层:
(1)解析wxml、wxss,负责页面的渲染(展示页面结构和样式)
(2)小程序中的每个页面都会维护一个页面的实例,每个页面都有唯一的pageId, 因此逻辑层能只是当前与之交互的page实例是哪一个
(3)一个页面的展示逻辑对于一个渲染线程,类似于webview或者iframe

由于小程序逻辑层与视图层是双线程的原因,他们之间的通信通过jsBridge进行消息通信:

逻辑层setData ===> jsBridge ====> 视图层更新视图
视图层响应用户操作 ===> jsBridge ===> 逻辑层进行用户操作逻辑处理

例:

    Page({
        bindViewTap: function(e) {
            e.mark.myMark === "last" // true
            e.mark.anotherMark === "leaf" // true
            this.setData({
                name:'test'
            })
        }
    })
    
    ~~~~

具体查看方式:
(1)查看小程序逻辑层,打开调式微信开发者工具---》document.getElementsByTagName('webview')查询所有webviw标签,包含渲染层和逻辑层
console里面输入document查看逻辑层代码
(2)微信小程序开发者工具是使用electron 开发的;通过document.getElementsByTagName('webview')[0].showDevTools(true)查看当前页小程序渲染层代码,
查看小程序组件wx-picker等看到,小程序组件是使用webComponent实现的,将所有逻辑封装在里面

2. 小程序底层代码解析
  1. 查看小程序底层代码方式,help()查看所有快捷命令,openVendor()打开小程序基础库存储位置。下面包含每个版本的基础库包的信息。该目录下包含两个执行文件wcc.exe,wcsc.exe;
    wcc.exe wcc Compiler -->编译 wxml --> js
    wxml == 动态 ==> js ==>VDom ==> html
    ./wcc -d index.wxml >> wxml.js
    wcsc --> WeChat Stylesheet Compile --> 编译 wxss
    ./wcsc -js index.wxss >> wxss.js
    rpx --> px
  2. 逻辑层 ===> WAService .js(基础库提供以下api的实现)
    Page App 生命周期 wx.get wx.set wx.req
    底层基础库 App Page wx
    衔接native 通信jsBridge这一层

    Foundation 基础模块(WeixinJSBridge 初始化 、环境变量的初始化、eventEmit、配置)
    通信机制 WeixinJSBridge
    wx api appServiceSDK wx 路由挂载
    Page App 生命周期 (逻辑层js的执行没有window等方法,因为小程序提供了js运行的执行环境-沙箱(evaluateScriptFile方法)) 类似微前端和node 虚拟机模块(vm)
    Page=()=>{

       WeixinJSBridge

    }

小程序逻辑层性能问题,
值的传递---拷贝传递,通过jsBridge通信不具有实时性
例:一次性setData多个数据,类型React, 对更新进行批处理。
js动画,无法通过js实时操作渲染层动画或者操作DOM,因此小程序提供了WXS

  1. 渲染层 wxml 动态 wxss WAWebview .js
    底层基础库
    虚拟dom(__virtualDOM__)==>页面的真实渲染结构 组件系统 提供基础组件(exparser)
    事件的监听 ==> 衔接native 通信jsBridge这一层==> 逻辑层
    接受动态新数据 ==> 页面去更新视图
    基本组件 picker
    通信机制 WeixinJSBridge
    Foundation 基础模块(通用的方法和事件、api)
    js 运行环境 wxs

        var decodeName = decodeURI("./page/component/index.wxml")
        var generateFunc = $gwx(decodeName)  ==>render 
        if (generateFunc) {
        var CE = (typeof __global === 'object') ? (window.CustomEvent || __global.CustomEvent) : window.CustomEvent;
        document.dispatchEvent(new CE("generateFuncReady", {
            detail: {
            generateFunc: generateFunc
            }
        }))
        __global.timing.addPoint('PAGEFRAME_GENERATE_FUNC_READY', Date.now())
        } else {
        document.body.innerText = decodeName + " not found"
        console.error(decodeName + " not found")
        }

    渲染层加载过程

    1. 加载 wxml ==>js ==>$gwx(生成render渲染器)
    2. 加载 wxss ==>js ==> eval()==>css ==>html
    3. history.push==>页面入栈
    4. 分发事件,底层基础库监听,收集generateFunc, 监听 数据的接受
  2. 小程序底层代码
    wxappUnpacker解码小程序代码WAService.js,WAWebview .js
  3. 双线程模型的问题
    线程之间通过消息通信, setData传递数据 数据太多 更新频率太快
    小程序框架
    vue uni/mpvue

    react taro

3. 小程序加载过程

image

二、小程序框架

wxml/wxss js json的问题,无法引入其他第三方包、无法进行压缩等代码优化
框架的用处

  1. 成熟的第三方包
  2. 工程化
  3. sass、less、postcss等

1.框架的分类
运行时:
基于客户端运行的过程,运行中维护框架的状态、数据等
例:mpvue uniapp magalo(保留了vue运行时) ==》 双向数据绑定、diff算法、虚拟dom

编译时:
上线之前编译模板的过程
例:wepy(类vue)、taro(类React)等自己开发的一套语言,上线前编译成为wxmlwxssjs
问题:必须使用特定的语法模板,固定的模板
优势:性能能够得到保障(对比运行时)

对比:

imageimageimageimage


千里之外
32 声望1 粉丝