云裂变营销网
标题:
微信小程序底层框架实现原理
[打印本页]
作者:
匿名
时间:
2023-3-10 10:03
标题:
微信小程序底层框架实现原理
双线程架构
是什么?
渲染层与逻辑层分别由两个线程管理,两个线程之间由 Native 层进行统一处理
渲染层的界面使用 webview 进行渲染。
多个页面对应多个 webview(最多 10 个)
逻辑层采用 JSCore 运行 JavaScript 代码
只有一个 APP 实例,所有 JS 都在一个线程中执行
对比单线程的优势
避免单线程中,由于资源加载而阻塞页面解析
将微信 SDK、底层基础库等放在 Native 层中,减少应用的包体积和网络请求数量
如何解决 H5 的安全问题
禁用部分 JS 操作:如获取 DOM、动态执行 JS 代码等
为 JS 提供沙箱环境
为什么需要提供 WXS
双线程架构中,频繁的跨线程通信(如手势识别等)会带来性能问题。
WXS 可以
在渲染层中
写部分逻辑,在渲染层单独处理部分频繁改变的数据
PageFrame
解决的问题
每个页面都是一个独立的 webview,其中包含大量内容。小程序如何快速新建并打开页面
原理
作为一个
模板
,其中引用了各种通用资源 js,当多次使用 PageFrame 创建页面时,这些自资源会使用本地缓存。
启动一个页面的步骤:
启动一个 webview
在其中初始化基础库,以及一些基础库的内部优化
注入 WXML 和 WXSS,小程序能在接收到页面初始数据之后马上开始渲染
Exparser
Exparser 是小程序的
组件组织框架
,基本参考 Shadow DOM 模型实现。
Shadow DOM 是 WebComponents 中的概念,它允许将隐藏的 DOM 结构附加到常规的 DOM 树中。可以选择外界是否能获取内部结构。
一些 HTML 标签是浏览器内置的 ShadowDOM 组件,如 video、button 等。这些组件不能作为 ShadowDOM 的宿主元素。
Shadow DOM 中的事件,可以选择是否冒泡至宿主元素外部
WXSS
和 css 的区别
新增了 rpx 单位,换算方式为屏幕宽度为 375px 时,1px = 2rpx
仅支持部分选择器
编译方式
WXSS 文件不在 webview 中渲染,而是提前编译为 js。 在该 js 中,会获取设备信息(屏幕宽度等),并以此将 rpx 转换为实际像素。 该 js 内容会通过 eval 进行执行,并最终生成 style 标签插入到页面中。
WXML 的编译:Virtual DOM
WXML 代码也会编译为 JS,生成一个 $gwx 函数,它用于生成虚拟 DOM。
$gwx 的返回值也是一个函数 generateFun, generateFun 接受模板渲染所需的动态数据,其返回值是虚拟 DOM 树。
事件通讯系统
通信机制
渲染层和逻辑层的通信都是通过 Native 层转发
iOS 是利用了 WKWebView 的提供 messageHandlers 特性
安卓是往 WebView 的 window 对象注入一个原生方法
在微信中封装为 WeiXinJSBridge 作为兼容层
在开发者工具中则是用 Websocket 对通信方法进行模拟
绑定事件
标签的所有 attribute 都会存在虚拟 DOM 的 attr 属性中,通过正则判断某个属性是否是绑定的事件,找出事件后为节点注册事件。
小程序的事件都是和 HTML 原生事件对应的(如 tap 对应 mouseup),最终会通过 window.addEventListener 添加原生事件的监听
触发事件
渲染层中,会拼接事件的 event 参数,创建一个 exparser 事件并触发,通过 sendData 向逻辑层通信
数据在两个线程中的传递
页面加载时,data 中的数据会以 JSON 字符串的形式传至渲染层。因此,
data 中的数据必须是可以转为 JSON 的类型
字符串,数字,布尔值,对象,数组
小程序框架
预编译
自己定义一套 DSL(语法规则),一般对应 React 或 Vue,通过源码的 AST 解析还原为微信小程序原生代码的形式
局限性:
React 或 Vue 出了新的语法,要兼容的话要扩展 DSL
兼容问题,小程序不支持的属性,无法编译
半编译半运行时:mpvue
基于类 vue 语法
将 template 编译为 wxml
在 vue 的 patch 流程中,不更新 DOM,而是触发 setData 来更新视图
纯运行时框架:remax
纯运行时框架要解决的问题
React / Vue 的视图更新都是基于
DOM API
的,但小程序的逻辑层并未提供任何操作节点的 API。
唯一的更新视图的方式,就是 setData。
解决思路:动态 template
WXML 提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。
使用模板时,通过 is 属性决定要使用的模板是哪一个。而 is 属性的取值可以用双括号语法从而使用 data 中的数据。
因此,实现的思路就是:
在 data 中实现一个类似虚拟 DOM 的对象,通过递归的形式在 WXML 中将其渲染为 template
更新 DOM 的流程,改为更改这个虚拟 DOM 对象,通过 setData 触发视图更新
欢迎光临 云裂变营销网 (https://www.yunliebian.com/yingxiao/)
Powered by Discuz! X3.4