一、原生小程序
1. 小程序底层架构
传统的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. 小程序底层代码解析
- 查看小程序底层代码方式,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 逻辑层 ===> 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
渲染层 wxml 动态 wxss WAWebview .js
底层基础库
虚拟dom(__virtualDOM__)==>页面的真实渲染结构 组件系统 提供基础组件(exparser)
事件的监听 ==> 衔接native 通信jsBridge这一层==> 逻辑层
接受动态新数据 ==> 页面去更新视图
基本组件 picker
通信机制 WeixinJSBridge
Foundation 基础模块(通用的方法和事件、api)
js 运行环境 wxsvar 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") }
渲染层加载过程
- 加载 wxml ==>js ==>$gwx(生成render渲染器)
- 加载 wxss ==>js ==> eval()==>css ==>html
- history.push==>页面入栈
- 分发事件,底层基础库监听,收集generateFunc, 监听 数据的接受
- 小程序底层代码
wxappUnpacker解码小程序代码WAService.js,WAWebview .js - 双线程模型的问题
线程之间通过消息通信, setData传递数据 数据太多 更新频率太快
小程序框架
vue uni/mpvuereact taro
3. 小程序加载过程
二、小程序框架
wxml/wxss js json的问题,无法引入其他第三方包、无法进行压缩等代码优化
框架的用处
- 成熟的第三方包
- 工程化
- sass、less、postcss等
1.框架的分类
运行时:
基于客户端运行的过程,运行中维护框架的状态、数据等
例:mpvue uniapp magalo(保留了vue运行时) ==》 双向数据绑定、diff算法、虚拟dom
编译时:
上线之前编译模板的过程
例:wepy(类vue)、taro(类React)等自己开发的一套语言,上线前编译成为wxmlwxssjs
问题:必须使用特定的语法模板,固定的模板
优势:性能能够得到保障(对比运行时)
对比:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。