【小程序八股文】系列之篇章二 | 小程序的核心机制

【小程序八股文】系列之篇章二 | 小程序的核心机制

  • 前言
  • 三、微信小程序原理与运行机制
  • 简述一下微信小程序的原理
    • 微信小程序的双线程的理解
      • 为什么不采用浏览器多线程模式?为什么是双线程?`(出发点:安全,快速,方便管控,迭代独立)`
      • 双线程模式的流程
      • 为什么要多个WebView
    • 微信小程序的通信机制的理解(双线程机制下的通信原理)
    • 微信小程序的界面渲染的整体流程
    • 微信小程序的数据驱动的理解
    • 微信小程序如何进行双向绑定?
    • 微信小程序,为什么使用js闭包?
  • 下篇笔记链接

前言

上一章中我们主要介绍两个部分的内容:一个是小程序的基础/背景,另外一个是小程序与其他平台的区别。
上一章笔记链接:
【小程序八股文】系列之篇章一 | 小程序基础及与其他产品区别
那么在这一篇章中,我们主要介绍小程序的核心机制,因为核心机制比较重要,所以我把它单独作为一章来写。

三、微信小程序原理与运行机制

这里主要是介绍小程序的原理及运行机制

简述一下微信小程序的原理

  1. 微信小程序采用 JavaScript、WXML、WXSS 三种技术进行开发,本质就是一个单页面应用,所有的页面渲染和事件处理,都在一个页面内进行,但又可以通过微信客户端调用原生的各种接口

  2. 微信小程序基于数据驱动的架构模式,也就是它的 UI 和数据是分离的,所有的页面更新,都需要通过对数据的更改来实现。

  3. 微信小程序是一个双线程的框架,也就是说渲染进程WebView和脚本进程JSCore是互相独立的。这两个进程分别管理微信小程序框架的两个组成部分视图层(也叫做渲染层)和逻辑层。其中,视图层View用来渲染页面结构,展现UI,逻辑层appService用来处理业务逻辑、数据及接口调用。它们分别在渲染线程和脚本进程中运行,并通过系统层 JSBridge 实现通信,实现 UI 的渲染、事件的处理。

    (从上面可以看除微信小程序具有三个层次:视图层(View),逻辑层(APP Service),系统层(Native);两个进程:渲染进程和脚本进程)。

    在这里插入图片描述

微信小程序的双线程的理解

为什么不采用浏览器多线程模式?为什么是双线程?(出发点:安全,快速,方便管控,迭代独立)

上面两个问题都是小程序双线程框架的背景。

  • 小程序双线程框架出发点是在保证微信安全的前提下提供一种轻量化,快速便捷的应用程序。这就需要同时兼顾安全和性能。而浏览器采用的是多线程的模式,会为每个标签页添加一个独立的渲染进程,每个进程之间的资源和行为互不干扰,虽然这样可以保证网页独立稳定的运行,但同时也消耗了较多的资源。网站是依赖于浏览器的,有关Web相关的技术比较全面,可以承载一些庞大的应用程序,但微信小程序的宿主是微信,定位也是轻量化,并不需要太过丰富的Web能力,因此,多线程的设计不能够很多好的满足微信小程序设计的初衷。

  • 跟网站于浏览器的关系相比,我认为小程序与微信的关系更加接近CodePen这类(一个前端编程神器)在线编程平台中每个程序案例与平台的关系。小程序的版本迭代是独立的,不依赖于微信。

  • 为了实现版本迭代的独立性,同时兼顾安全性(禁止程序操作DOM),一般有两种方法,一种是采用Web Worker, 另外一种是采用Shadow DOM。但Shadow DOM 的兼容性较差,不适合推广,因此,采用类似Web Worker的方案更加现实。但Web Worker 非常耗费资源,无法兼顾小程序轻量化的要求,因此,小程序采用一种类似Web Worker的新方案,也就是双线程模式。

    【拓展】

    • Web Worker 和Shadow DOM
      • Web Worker 是线程安全的,Worker 内的 JavaScript 代码无法获取 Window 和 Document 对象,也就无法操作 DOM。除此之外,由于 Worker 的线程安全特性,Worker 内的代码运行过程中不会阻塞外层的 GUI 渲染线程,两者可以并行。
      • 而 Shadow DOM 是 Web Components 规范的一部分,将 ShadowRoot 的模式设置为 closed 就可以禁止获取到 ShadowRoot 节点,从而也无法操作其内部的 DOM。
    • Web Worker
      从名字上就可以看出,web worker就是在web应用程序中使用的worker。这个worker是独立于web主线程的,是一个运行在后台的JS线程,不会影响页面的响应。如果将 docs 表格中复杂计算放到主线程中,页面不仅可能卡顿,甚至可能崩溃掉。将计算挪入 web worker 中,将计算结果事件回调的方式返回,可以让用户使用更加流畅。
  • 采用双线程模式也可以更加方便对小程序的管控。跟Web Worker类似,小程序将业务及数据的处理独立于页面的渲染进程,即使用类似Web Worker 的独立线程运行逻辑,使用 Webview 渲染 UI。但不同的是,小程序并没有使用Web Worker 子线程,而是一个独立的“主线程”,这样子可以保证更好的性能,其实本质上也是做沙盒的思想。
    在这里插入图片描述渲染线程使用 Webview 进行 UI 的渲染呈现。Webview 是一个完整的类浏览器运行环境,本身具备运行 JavaScript 的能力,但是小程序并不是将逻辑脚本放到 Webview 中运行,而是将逻辑层独立为一个与 Webview 平行的线程,使用客户端提供的 JavaScript 引擎运行代码,iOS 的JavaScriptCore、安卓是腾讯 X5 内核提供的 JsCore 环境以及 IDE 工具的 nwjs 。

    • 使用客户端系统的JavaScript 引擎提供一个沙箱环境来运行开发者的 JavaScript代码(安全管控需求)
    • 并且逻辑线程是一个只能够运行 JavaScript 的沙箱环境(这个沙箱环境只提供纯 JavaScript 的解释执行环境,没有任何浏览器相关接口)。不提供 DOM 操作相关的 API,所以不能直接操作 UI,只能够通过 setData 更新数据的方式异步更新 UI。

双线程模式的流程

在这里插入图片描述

  • 在小程序中,选择了 Hybrid的渲染方式,将视图层和逻辑层是分开的,双线程同时运行,视图层的界面使用 WebView进程进行渲染,逻辑层运行在 JSCore进程中。
  • WebView 主要处理 WXML 和 WXSS,负责渲染等工作,多个页面会创建多个 WebView 线程。WebView直译是网页视图,就是原生应用中的浏览器引擎。简单来说 webview 是手机中内置了一款高性能 webkit 内核浏览器,不过没有提供UI(地址栏、导航栏),只是单纯的展示一个网页界面。
  • JsCore 主要执行业务逻辑代码。
  • 渲染层和逻辑层通过 Native 来进行通信。例如请求数据WebSocket 都是通过 Native 来执行后给 JsCore 处理或者给 WebView 来渲染。
  • 小程序中为了达到多页面体验的功能,需要使用到多个WebView,每个WebView对应的就是一个小程序的页面。WebView和JsCore这两个线程的通信会经由微信客户端(下文中也会采用Native来代指微信客户端)做中转,线程之间的通讯、数据的传递以及逻辑层发送网络请求也都是经由Native转发

为什么要多个WebView

多个WebView可以理解为多页面应用,其实是有区别于单页面应用SPA的,SPA渲染页面是通过路由识别以后去动态地将页面挂载到root节点里,如果SPA打开一个新页面,是需要卸载掉当前的页面,然后重新渲染。很显然,只有通过多个WebView才能更加接近原生应用APP的用户体验。

💡 既然一个页面一个WebView线程,那每一page线程都有对应的js线程吗?还是js线程是处理所有page线程的逻辑呢?
逻辑线程是跟页面无关的,只负责执行js代码,而且小程序同一时间只能显示一个页面,所以同一个逻辑线程可以支持所有的渲染线程。

微信小程序的通信机制的理解(双线程机制下的通信原理)

小程序的通信机制——WeixinJSBridge
在这里插入图片描述

  • 在小程序中,选择了 Hybrid的渲染方式,将视图层和逻辑层是分开的,双线程同时运行,视图层的界面使用 WebView进程进行渲染,逻辑层运行在 JSCore进程中。
  • 线程的通信是通过Native(理论上是微信客户端)做中转来处理或者转发信息,具体来说,就是Native分别在渲染层逻辑层注入WeixinJSBridge(微信内置浏览器私有接口),渲染层逻辑层可以与Native通信。
  • 微信内置浏览器私有接口WeixinJSBridge是微信浏览器的一个内置的JavaScript库,它提供了一系列的API,可以让网页调用微信客户端的功能。
  • WeixinJSBridge提供了渲染层NativeNative逻辑层之间消息通讯的机制。
  • 逻辑层和渲染层的通信会由 Native (微信客户端)做中转,逻辑层发送网络请求也经由 Native 转发。

为了保持与真实环境的一致,微信开发者工具没有新增或者删除WeixinJSBridge的方法,只是在WeixinJSBridge的基础上进行了方法的重构。

window.WeixinJSBridge = {
  on: c,
  invoke: e,
  publish: t,
  subscribe: o,
}
  • on:主要用来收集小程序开发者工具触发的事件回调。
  • invoke:以api的方式调用开发者工具提供的基础能力,并提供对应api执行后的回调
  • publish:主要用来向逻辑层发送信息,也就是说要调用逻辑层的事件方法
  • subscribe:主要用来收集逻辑层触发的事件回调,和publish配套,就像javascript中的发布订阅模式。

微信小程序的界面渲染的整体流程

在这里插入图片描述小程序的逻辑层和渲染层是分开的两个线程。在渲染层,宿主环境会把WXML转化成对应的JS对象,在逻辑层发生数据变更的时候,我们需要通过宿主环境提供的setData方法把数据从逻辑层传递到渲染层,再经过对比前后差异,把差异应用在原来的Dom树上,渲染出正确的UI界面。

小程序更新视图数据的通信流程

  1. 在渲染层把 WXML 转化成对应的 JS 对象。
  2. 在逻辑层发生数据变更的时候,通过宿主环境提供的 setData 方法把数据从逻辑层传递到 Native,再转发到渲染层。
  3. 经过对比前后差异,把差异应用在原来的 DOM 树上,更新界面。

界面渲染整体流
wxml 可以等价于一棵 DOM 树,另外也可以使用一个 js 对象来模拟 DOM 树,简称虚拟 DOM
1.在渲染层,宿主环境会把 WXML 转化成对应的j s 对象;
2.将 js 对象再次转成真实 DOM 树,交由渲染层线程渲染;
3.数据变化时,逻辑层提供最新的变化数据,js 对象发生变化比较进行 diff 算法对比;
4.将最新变化的内容反映到真实的 DOM 树中,更新界面;

会调用 WeixinJSBridge,将数据反馈给 视图层所以一次完整的用户事件可大致如下:
1、渲染层 -> Native (点击事件)
2、Native -> 逻辑层 (点击事件)
3、逻辑层 -> Native (setData)
4、Native -> 渲染层 (setData)

微信小程序的数据驱动的理解

在JS文件中的data中动态操控数据:使用 this.setData方法修改视图层data中的数据;
在wxml文件通过{{}}将数据绑定,即可在页面中显示

注意:
直接修改this.data,而不调用this.setData(),是无法改变当前页面的状态,会导致数据不一致
仅支持可以JSON化的数据
单次设置的数据不能超过1024KB,尽量避免一次设置过多的数据
不要把data中的任何一项的value设为undefined,否则这一项将不能被设置,可能会有潜在的问题

微信小程序如何进行双向绑定?

  1. 通过bind-tap点击事件 向app.js 定义的方法中获取回执
  2. 设置data的值 实现双向绑定

微信小程序,为什么使用js闭包?

因为微信小程序处理函数是异步执行的,异步执行造成的结果可能和预期的不合,如果函数中有循环,最后的结果都一样,所以使用js闭包可以解决这个问题。

下篇笔记链接

【小程序八股文】系列之篇章三 | 小程序的事件及生命周期
下篇笔记链接:【待更新】
下篇笔记内容:【待更新】

原创笔记,未经同意请勿转载

码字不易

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/643819.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2.Redis之Redis的背景知识

Redis 是一个在内存中存储数据的中间件 用于作为数据库,用于作为数据缓存. 在分布式系统中能够大展拳脚~ 1.Redis的特性介绍(优点) 1.1 在内存中存储数据 MySQL 主要是通过"表"的方式来存储组织数据的,"关系型数据库" Redis 主要是通过“键值对" 的…

safetensors介绍

1 介绍 safetensors 是 Huggingface 推出的一种可靠、易移植的机器学习模型存储格式,用于安全地存储 Tensor,而且速度很快(零拷贝)。 safetensors 格式结构: 8 bytes:一个无符号的整数,表示…

1106 2019数列

solution 维护长度为4的数组&#xff0c;对于第四位之后的数字&#xff0c;为所维护数组的所有元素之和 的个位数 #include<iostream> using namespace std; int main(){int n, a[4] {2, 0, 1, 9}, cnt 0, d;scanf("%d", &n);for(int i 0; i < n; …

WSL2添加桌面显示

编译 autoscan && aclocal && autoconf && automake --add-missing 自动 #!/bin/shrun () {echo "running: $*"eval $*if test $? ! 0 ; thenecho "error: while running $*"exit 1fi }run aclocal run autoheader run automak…

k8s命令式对象管理和配置

kubectl补全: # dnf install -y bash-completion # echo "source <(kubectl completion bash)" >> ~/.bashrc # kubectl completion bash > /etc/bash_completion.d/kubectl 命令式对象管理 kubectl命令 # 查看所有pod kubectl get pod # 查看某个po…

01-02.Vue的常用指令(二)

01-02.Vue的常用指令&#xff08;二&#xff09; 前言v-model&#xff1a;双向数据绑定v-model举例&#xff1a;实现简易计算器Vue中通过属性绑定为元素设置class 类样式引入方式一&#xff1a;数组写法二&#xff1a;在数组中使用三元表达式写法三&#xff1a;在数组中使用 对…

Python3 笔记:IDLE的几个基本设置

1、设置字体&#xff1a; Options > Configure IDLE > Fonts 2、设置文字颜色&#xff08;设置高亮&#xff09;&#xff1a; Options > Configure IDLE > Highlights 3、设置背景颜色&#xff1a; Options > Configure IDLE > Highlights 4、设置窗口&a…

存储+调优:存储-IP-SAN-EXTENSION

存储调优&#xff1a;存储-IP-SAN-EXTENSION 文件系统的锁标记 GFS&#xff08;锁表空间&#xff09; ----------- ------------ ------------- 节点 | ndoe1 | | node2 | | node3 | ---------- ------…

树莓派学习笔记——树莓派的三种GPIO编码方式

1、板载编码&#xff08;Board pin numbering&#xff09;: 板载编码是树莓派上的一种GPIO引脚编号方式&#xff0c;它指的是按照引脚在树莓派主板上的物理位置来编号。这种方式对于初学者来说可能比较直观&#xff0c;因为它允许你直接根据引脚在板上的位置来编程。 2、BCM编…

钉钉算是在线办公系统的设计标杆,尽管它依然很难用

不吹不黑&#xff0c;钉钉界面谁的的确简洁&#xff0c;无奈它面向的是场景复杂的办公领域&#xff0c;导致其越来越臃肿难用&#xff0c;反正我是该研究研究&#xff0c;但绝对不会用的。 举报 评论 1

如何下载Axure pr 9 免费使用 汉化版本

下载包得链接 链接&#xff1a;https://pan.baidu.com/s/17FSx5XfL1TAoU6Sz67yifw?pwdff00 提取码&#xff1a;ff00 然后一直下一步就行 打开软件 授权码&#xff1a; 被授权人&#xff08;License&#xff09;:AX9001 授权码&#xff08;Key&#xff09;&#xff1a;iy9u…

韭菜的自我总结

韭菜的自我总结 股市技术面量价关系左侧右侧右侧技术左侧技术洗盘 韭菜的自我修养虚拟货币的启示韭菜的买入时机韭菜的心理压力成为优秀玩家的关键 股市技术面 技术面分析可以作为买卖时机判定的工具&#xff0c;但是投资还是需要基本面的分析作为支撑。也就是基本面选股&…

springboot项目,@Test写法 @Before @After

某文件示例 package cn.xxx.crm.boss;import cn.xxxx.crm.manager.mq.rabbit.AliyunCredentialsProvider; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; im…

Plotly库利用滑块创建数据可视化

使用了Plotly库来创建一个数据可视化图表&#xff0c;并使用滑块来控制显示哪些数据 import plotly.graph_objects as go from plotly.subplots import make_subplots# 示例数据 x [1, 2, 3, 4, 5] y1 [1, 2, 3, 4, 5] y2 [5, 4, 3, 2, 1] y3 [2, 3, 1, 5, 4]# 创建子图 f…

【Linux取经路】线程同步——条件变量

文章目录 前言一、条件变量1.1 pthread_cond_init——初始化一个条件变量1.2 pthread_cond_destroy——销毁一个条件变量1.3 定义一个全局的条件变量1.4 pthread_cond_wait——等待条件满足1.5 pthread_cond_signal——唤醒一个等待线程1.6 pthread_cond_broadcast——唤醒所有…

企业级架构及本体论最新进展

本文主要探讨了企业级架构和本体论的新兴趋势&#xff0c;特别是DoDAF、IDEAS、UAF和NAF的发展历程、理论基础、模型构建以及与ArchiMate和语义网技术的关联。原文: The emerging landscape of Enterprise Architecture and Ontology 导言 动机和采用的方法 关注我的人都知道我…

把自己的垃圾代码发布到官方中央仓库

参考博客&#xff1a;将组件发布到maven中央仓库-CSDN博客 感谢这位博主。但是他的步骤有漏缺&#xff0c;相对进行补充 访问管理页面 网址&#xff1a;Maven Central 新注册账号&#xff0c;或者使用github快捷登录&#xff0c;建议使用github快捷登录 添加命名空间 注意&…

SecureCRT for Mac注册激活版:专业终端SSH工具

SecureCRT是一款支持SSH&#xff08;SSH1和SSH2&#xff09;的终端仿真程序&#xff0c;简单地说是Windows下登录UNIX或Linux服务器主机的软件。 SecureCRT支持SSH&#xff0c;同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的理想工具。通过…

Echarts图表使用

ECharts是一个用JS实现开源可视化库&#xff0c;它提供了丰富的图表类型和交互能力。使用户可以通过简单的配置生成各种各样的图表。 先安装ECharts图表直接下载echarts.min.js并用<script>标签引入也可以使用源代码版本echarts.js并用<script>标签引入&#xff0…

英语学习笔记25——Mrs. Smith‘s kitchen

Mrs. Smith’s kitchen 史密斯太太的厨房 词汇 Vocabulary Mrs. 夫人【已婚】 复习&#xff1a;Mr. 先生 全名 / 姓    Mrs. 夫人 全名 / 丈夫的姓    Miss 小姐&#xff08;未婚&#xff09; 全名 / 姓    Ms. 女士 全名 / 姓 查看婚姻状况&#xff0c;可以观察…