【小步调 - 大聪明】深入微信小步调的核心原理

[复制链接]
发表于 2026-1-26 14:05:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×





课程目的

本次课程紧张通过背景管理小步调回顾一下小步调的高阶语法,然后解说团体小步调流程原理:


  • 前端相干的编码规范、筹划规范
  • 页面切换、生命周期、数据通讯等根本知识
  • 双线程架构、webview 渲染、PageFrame 模板、通讯体系、生命周期、跨端框架等
  • 掘金小册保举  
配景



https://zh.wikipedia.org/zh-cn/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F
双线程架构

口试官:说说什么是历程?什么是线程?区别? | web前端口试 - 口试官系列

历程:利用体系举行举行资源分配和调理的根本单元
线程:利用体系可以大概举行运算调理的最小单元,其是历程中的一个实验使命(控制单元),负责当前历程中步调的实验

微信小步调的筹划和前端欣赏器是不同等的,它隔离了 JS 利用层 和 界面渲染层,前端是互通的,可以通过 window document 恣意的调用 dom 元素和实验脚本,但是小步调作为微信的工具,势必不允许像 web 端如许自由的利用空间,以是:

  • App Service(逻辑层):单纯实验 JavaScript 的沙箱情况,无法利用 Dom 和访问欣赏器 Api ,只能借助 Native 异步查询 DOM 元素并利用,小步调的 WXML 和 WXSS 也会被编译为 JS 脚本举行注入利用。由于小步调内部只有一个 App 实例,通过这个 App 主线程 举行调理
  • Web View(渲染层):单纯页面的展示,模拟 app 多页面模式,具有多个 webview ,可以临时抽象成 欣赏器的 tab 页面(并非 VUE 的单页面结构,像 App 多页面结构)
  • Native(微信客户端):利用微信缓存机制,提前注入 微信 SDK、接口哀求、组件渲染(wx.request、wx.showToast 都是存放在这里)
WebView 结构



  • 第一阶段是启动一个 WebView,在iOS和 Android 体系上,利用体系启动WebView都必要一小段时间。
  • 第二阶段是在 WebView 中初始化根本库,此时还会举行一些根本库内部优化,以提升页面渲染性能。
  • 第三阶段是注入小步调 WXML 结构和 WXSS 样式,使小步调能在吸收到页面初始数据之后立即开始渲染页面(这一阶段无法在小步调启动前实验)。
  • 每一个页面都独立运行在一个页面层级上。小步调启动时仅有一个页面层级,每次调用 wx.navigateTo,都会创建一个新的页面层级,wx.navigateBack 会烧毁一个页面层级。


  • 微信开发者工具底层是 Chrome XWeb 内核,举行开发跨平台的桌面应用(如QQ、WeChat客户端)。
  • 左上角选择,微信开发者工具 -> 调试 -> 调试微信开发者工具,和谷歌调试界面险些如出一辙(利用这个工具,我们后续可以处置惩罚一些内部报错的调试BUG)。
  • 接下来,我们利用脚本遍历开发工具的 webview 元素。
  1. // 获取所有的 webview
  2. document.getElementsByTagName('webview')
  3. // 打开调试的 webview
  4. document.getElementsByTagName('webview')[0].showDevTools(true, null)
复制代码

  • webview 的寄义如下:当前小步调的页面 两个渲染层 逻辑层 调试器
  • 新开一个页面就会新增一个 webview,微信限定最多10个以包管性能题目的底层缘故因由
  • 利用下令打开一个 webview 页面举行详细的调试
  • 页面的样式、调试库、渲染库、开发工具的设置…
  • body 下面的标签就是利用 小步调开发的 Exparser 框架将 dom 转换为自界说组件的一套规则
  • 每个 webview 都加载了这么多文件,是怎样包管高效运作的?
快速渲染 PageFrame


  • 利用 page frame 模板天生 webview 视图。
  • 根本的 webview 模板和之前打开的同等,但是包罗一些解释占位符,后续会被编译为详细的实验 js 文件。
加载流程如下:

  • 首页启动时,即第一次通过 pageframe.html 天生内容后,背景服务会缓存 pageframe.html 模板初次天生的html内容。

    • 非初次新打开页面时,页面哀求的 pageframe.html 内容直接走背景缓存。
    • 非初次新打开页面时,pageframe.html 页面引入的外链js资源(如上图所示)走本地缓存。

  • 天生 webview 模板后,初始化 webview 地点 http://127.0.0.1{global.proxyPort}/aboutblank?${c} 空隙点,此中 ${c} 为对应 webview 的 id。
  • 监听页面的 ready 利用,注入实验代码脚本天生终极的 webview 地点和实验代码。
编译原理

根本语法不作过多赘述,紧张编译原理和rpx动态适配。WXSS/WXML并不可以直接实验在webview层举行渲染,通过wcsc/wcc实验脚本编译为js文件,然后注入webview中,这里可以演示一下。
  1. // help() 查看编译命令
  2. help()
  3. // 编译 WXSS 命令
  4. ./wcsc -js index.wxss >> style.js
  5.   // 编译 WXML 命令
  6. ./wcc -js index.wxml >> test.js
  7. // 执行 $gwx 文件
  8. var decodeName = decodeURI("./pages/home-tab/index.wxml")
  9. var generateFunc = $gwx(decodeName)
  10. generateFunc()
复制代码
  1. var eps = 1e-4
  2. var transformRPX =
  3.   window.__transformRpx__ ||
  4.   function (number, newDeviceWidth) {
  5.     if (number === 0) return 0
  6.     number = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth)
  7.     number = Math.floor(number + eps)
  8.     if (number === 0) {
  9.       if (deviceDPR === 1 || !isIOS) {
  10.         return 1
  11.       } else {
  12.         return 0.5
  13.       }
  14.     }
  15.     return number
  16.   }
复制代码

  • wcsc 将 WXSS 编译为 JS 文件。
  • JS 文件注入到 WebView 中。
  • 逻辑层实验 JS 文件,紧张是装备信息获取(宽度、高度、横屏)、特定规则 rpx 适配为 px,写入编译后的 CSS 文件到 head style 头部。
  • WCC 将 WXML 编译为 JS 文件。
  • 但是文件作了压缩肴杂,本质逻辑实验 $gwx 函数。
  • generateFunc 就是担当动态数据,并天生假造 DOM 树的函数,DOM 树已存在的数据直接渲染为 wx-view/wx-text,必要 JS 脚本异步获取的数据接纳 tag: virtual 假造 DOM 元素举行占位,比及获取后端数据之后直接添补 => 真实 DOM。
Exparser

WebComponents Shadow Dom
Exparser是微信小步调的组件构造框架,内置在小步调根本库中,为小步调提供各种各样的组件支持。内置组件和自界说组件都有Exparser构造管理。
这部分反面单独抽离一篇文章举行解说…
通讯体系

在正式解说小步调的通讯体系前,先来熟悉一下小步调的 发布 - 订阅模式

美团一面:你相识发布-订阅模式吗?「天天搞透一道JS手写题💪Day8」 - 掘金
概述:引入中心平台举行注册和关照,有用办理了观察者维护列表导致的解耦不彻底题目
观察者通过 on 向 EventBus 注册变乱,然后 Subject 通过 emit 向 EventBus 发射变乱,由 EventBus 来向观察者更新。本质上是维护一个 events 对象,通过变乱名注入到 events,每个 变乱名 内里都有相应的回调函数,发布之后会分发到相应变乱 回调函数 的方法。
  1. class PubSub {
  2.   constructor() {
  3.     this.events = {};
  4.   }
  5.   subscribe(event, callback) {
  6.     if (typeof event !== 'string') {
  7.       throw new Error('Event name must be a string');
  8.     }
  9.     if (typeof callback !== 'function') {
  10.       throw new Error('Callback must be a function');
  11.     }
  12.     if (!this.events[event]) {
  13.       this.events[event] = [];
  14.     }
  15.     this.events[event].push(callback);
  16.   }
  17.   unsubscribe(event, callback) {
  18.     if (typeof event !== 'string') {
  19.       throw new Error('Event name must be a string');
  20.     }
  21.     if (typeof callback !== 'function') {
  22.       throw new Error('Callback must be a function');
  23.     }
  24.     if (!this.events[event]) return;
  25.     this.events[event] = this.events[event].filter(cb => cb !== callback);
  26.   }
  27.   publish(event, data) {
  28.     if (typeof event !== 'string') {
  29.       throw new Error('Event name must be a string');
  30.     }
  31.     if (!this.events[event]) return;
  32.     this.events[event].forEach(callback => callback(data));
  33.   }
  34. }
复制代码

在微信小步调实验过程中,Native层(客户端层)分别向渲染层与逻辑层注入 WeixinJSBridge 以到达线程通讯的目的,前面也提到了 webview 脚本注入的原理,WeixinJSBridge 提供了如下几个方法:


  • invoke - 调用 Native API,以api方式调用开发工具提供的根本本领,并提供对应api实验后的回调
  • invokeCallbackHandler - Native 通报 invoke 方法回调效果
  • on - 用来网络小步调开发者工具触发的变乱回调
  • publish - 渲染层发布消息,用来向逻辑业务层发送消息,也就是说要调用逻辑层的变乱方法
  • subscribe - 订阅逻辑层消息
  • subscribeHandler - 视图层和逻辑层消息订阅转发
  • setCustomPublishHandler - 自界说消息转发


  • WXML 渲染为假造 DOM,添加 addEventListener 举行变乱剖析。
  • 逻辑层剖析的时间会利用 JSBridge subscribe 订阅变乱名称到渲染层,实验逻辑还在逻辑层,只是把名称和详细代码在渲染层作了映射。
  • 触发变乱,渲染层发布消息 publish 携带方法名颠末 JSBridge 到达逻辑层。
  • 逻辑层实验将 Data 以 JSON 字符串格式的数据颠末 JSBridge 渲染给 WXML。
生命周期



  • onLaunch(App onLaunch) App 主应用开始初始化,逻辑线程开始实验。
  • onLoad(Object query) 页面加载时触发,一个页面只会调用一次,可以在onLoad的参数中获取打开当前页面路径中的参数。
  • onShow() 页面体现/切入前台时触发。
  • onHide() 页面隐蔽/切入背景时触发。如 wx.navigateTo 或底部 tab 切换到其他页面,小步调切入背景等。
  • onReady() 页面初次渲染完成时触发。一个页面只会调用一次,代表页面已经预备妥当,可以和视图层举行交互。
  • onUnload() 页面卸载时触发。如 wx.redirectTo 或 wx.navigateBack 到其他页面时。


  • wx.navigateTo 方式是创建新的 webview(添加新的页面栈,新到场的页面重新渲染,之前的页面 onHide 隐蔽,为了利用 navigateBack 走缓存 onShow)。
  • wx.redirectTo 以及 wx.navigateBack 是通过更新自身 webview 举行页面转换的,以是当前页面会举行卸载利用,而且重新天生新页面。
根本库解包


微信开发者工具内里选择的根本库为微信中的根本库版本(反面标识了兼容性和用户的数量),可用于微信开发者工具内的调试。每个版本的微信客户端都会自带一个版本的小步调根本库,而不是微信客户端带着全部版本的根本库,以是开发时选择的版本只管和客户端的同等(最新的为好),制止 API 兼容性题目。

接下来,我们利用 openVendor() 找到 根本库举行剖析,找到原始的 wxvpkg 然后利用 Github 工具举行反编译出源码,https://github.com/csj5588/wxappUnpacker

构建后的效果在 dist 文件下,本质上照旧渲染层和逻辑层两个线程脚本之间的交互流程,后续在深入探究。
跨端框架

由于小步调语法较为原始,工程化工具不支持,市面上太多平台的小步调必要适配开发,基于此市面上的第三方框架也渐渐进入大众的视野,现在来说盛行的就是 taro 和 uni-app。
下面先来先容下框架的分类:
预编译


本质上是利用 DSL(语法规则) + 语法剖析,将一些逻辑转换为小步调支持的语法,但是如许存在一些题目:


  • 如果React大概Vue后期再出一些新特性的话,预编译框架都必要举行语法剖析扩展编写。
  • 兼容题目,比如小步调不支持的一些属性,如果不支持,预编译框架要举行兼容。
半编译半运行


根本上运行时的框架都是参考Vue的框架才可以到达运行时的目的,注意小步调是不支持直接利用DOM元素的,以是只必要将Vue的patch挂载真实DOM流程修改为小步调setData的逻辑,template转换为WXML,style适配下规则就可以。
mpvue (github地点请拜见)是一个利用Vue.js开发小步调的前端框架。框架基于Vue.js核心,mpvue修改了Vue.js的runtime和compiler实现,使其可以运行在小步调情况中,从而为小步调开发引入了整套Vue.js开发体验。
下面我们来看一下源码是怎样实现的?



  • 修改了 vue 的 patch 阶段举行 this.$updateDataToMP()方法。
  • 在this.$updateDataToMP()方法就举行了setData的一个调用,还举行了diffData数据的比对和throttle函数优化双线程通讯的性能。
运行时框架

运行时框架紧张办理必要 template 转换为 WXML 这部分逻辑,这部分可以借助小步调的template模版机制来举行办理。


如许的话我们只必要举行 root 数据的利用即可,利用完成后利用 setData 渲染机制 发送到渲染层举行利用即可,Taro4 我看编译的效果似乎也是按照如许的格式利用的,后续再看看。
主流技能

Taro


Taro 先容 | Taro 文档
Taro 特点总结


  • 接纳 TypeScript (TS) 加上部分 Rust 举行开发
  • 底层标准参考 微信小步调,兼容性较好,其他平台的兼容性未知
  • 对 React 和 Webpack 语法有精良的兼容性支持,Vue 3 加上 Vite 新推出,也可以用
  • 调试开发必要下载差别平台的工具,无法直接导出运行
  • 在 GitHub 上搜刮近两年 stars 30+ 的开源项目,资源只有一页,体现资源较少
  • 不支持利用 Vue 3 的 scoped CSS 样式隔离语法,这大概必要更详细的先容
资源链接
Taro UI | O2Team
NutUI - 移动端组件库
组件库选择发起


  • Taro 组件库:由 Taro 维护,但不保举安装
  • NutUI 组件库:多端组件库分离,保举作为开发的首选
uni-app


uni-app官网
相干资源链接


  • uview-plus 3.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架
  • GitHub - Moonofweisheng/wot-design-uni: 一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自界说主题。
  • 页面 | uni-app官网
uni-app 特点总结
本质上有两种体系:


  • 一种是 uniapp + HBuilder 工具构建的一套自己的规范,此中包罗:uts(TypeScript 超集)、uni-modules (依靠管理)、uvue(编译语言)、uniCloud(云服务),终极这些被 uni-app x 同一集成,必要重新学习一套标准、时间本钱和难度过高,编辑器也不如前端常用的编辑器 VSCode、WebStorm
  • 另一种可以借助本来的下令行实验,和其他的前端项目同等,可以借助第三方优质模板,但是注意 app 部分打包仍旧必要 HBuilder 开发工具(保举)
汇总

维度Taro得分Uni-app得分社区文档清晰明确8较为紊乱、自有体系和前端不兼容6上手本钱VUE 版本上手容易、React 较高8底层接纳 VUE 开发,熟悉水平更高9开源项目 pushed:>2023-09-01 stars:>3068714310Github 活泼stars:35.3k+ issues:1.2k + 1w+10stars:39.9k+ issues:0.9k + 3k+8三方组件库官方组件库同一,资源优质 NutUI VUE 6k+9官方组件库较为大抵、社区UI生态较差、大部分收费、一部分不敢用5TS 支持兼容性精良9兼容性精良8VUE 语法兼容兼容大部分 VUE 语法7兼容大部分 VUE 语法8React 语法兼容支持0不支持0总计🥇🏅🎖️5854跨端开发框架深度横评
下周安排

开源商城项目拆解


  • 腾讯有数
  • gz-yami - Overview
  • EastWorld
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表