We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
为了能够兼顾体验好和在线版本更新,小程序采用了客户端原生技术与web技术结合的混合技术(简称Hybrid技术)来渲染,这么做有以下好处:
小程序的渲染层和逻辑层分别由2个线程管理:视图层的界面使用了WebView进行渲染,逻辑层采用JsCore线程运行JS脚本。
那为什么要这样设计呢,前面也提到了管控和安全,为了解决这些问题,我们需要阻止开发者使用一些API,例如浏览器的window对象,跳转页面、操作DOM、动态执行脚本的开放性接口。
逻辑层只提供纯JavaScript的解释执行环境,没有任何浏览器相关接口。
小程序双线程模型各模块功能:
逻辑层:创建一个单独的线程去执行JavaScript,在这里执行的都是有小程序业务逻辑的代码,负责逻辑处理、数据请求、接口调用等
视图层:界面渲染相关的任务都在WebView线程里执行,通过逻辑层代码去控制渲染哪些界面。一个小程序存在多个界面,所以视图层存在多个WebView线程
JSBridge起到架起上层开发与Native(系统层)的桥梁,使得小程序可通过API使用原生的功能,且部分组件为原生组件实现,从而有良好体验
把开发者的JS逻辑代码放到单独的线程去运行,但在WebView线程里,开发者没法直接操作DOM。
那如何实现动态更新页面呢?
如上图所示,逻辑层和视图层的通信会由微信客户端(下文中会采用Native来代指微信客户端)做中转,逻辑层发送网络请求也经由Native转发。
所以 DOM 更新也是可以通过数据通信来实现的,Virtual DOM流程大致是:用JS对象模拟DOM树 => 比较两颗虚拟DOM树的差异 => 把差异应用到真正的DOM树上。
如图:
1. 在渲染层把WXML转化为对应的JS对象。 2. 在逻辑层发生数据变更的时候,通过宿主环境提供的setData方法把数据从逻辑层传递到Native,再转发到渲染层。 3. 经过对比前后差异,把差异应用在原来的DOM树上,更新界面。
我们通过把WXML转化为数据,通过Native进行转发,来实现逻辑层和渲染层的交互和通信。
小程序的能力需要Native来支撑,而这离不开小程序基础库
小程序的基础库可以被注入到视图层和逻辑层运行,主要用于以下几个方面:
- 在视图层,提供各类组建页面的元素 - 在逻辑层,提供各类API来处理各种逻辑 - 处理数据绑定、组件系统、事件系统、通信系统等一系列框架逻辑 - 自定义组件和插件
所以我们可以看到,小程序的基础库主要包括:
小程序的基础库不会被打包在某个小程序的代码包里边,他会被提前内置在微信客户端。
这样做的好处:
Exparser 是微信小程序的组件组织框架,内置在小程序基础库中,为小程序的各种组件提供基础的支持。小程序内的所有组件,包括内置组件和自定义组件,都由Exparser组织管理。
Exparser的主要特点包括以下几点:
基于这个框架,内置了一套组件,以涵盖小程序的基础功能,便于开发者快速搭建出任何界面。同时也提供了自定义组件的能力,开发者可以自行扩展更多的组件,以实现代码复用。
小程序基于Exparser框架,内置了一套组件,提供了视图容器类、表单类、导航类、媒体类、开放类等几十种组件
内置组件在小程序框架里的定义是:在小程序架构里无法实现或者实现不好某类功能,使用组件内置到小程序框架里。 常见组件有:
###API 宿主环境提供了丰富的API,可以很方便的调起微信提供的能力。 小程序提供的API按照功能主要分为几大类:网络、媒体、文件、数据缓存、位置、设备、界面、界面节点信息还有一些特殊的开放接口。
需要注意API调用大多数都是异步的。
###自定义组件 自定义组件是开发者可以自行扩充的组件。开发者可以将常用的节点树结构提取成自定义组件,实现代码复用。
在使用自定义组件的小程序页面中,Exparser 将接管所有的自定义组件注册与实例化。以 Component 为例:
Page 构造器的大体运行流程与之相仿,只是参数形式不一样。这样每个页面就有一个与之对应的组件,称为“页面根组件”。
在初始化页面时,Exparser 会创建出页面根组件的一个实例,用到的其他组件也会响应创建组件实例(这是一个递归的过程)。
插件是对一组 js 接口、自定义组件或页面的封装,用于嵌入到小程序中使用。
插件不能独立运行,必须嵌入在其他小程序中才能被用户使用;而第三方小程序在使用插件时,也无法看到插件的代码。因此,插件适合用来封装自己的功能或服务,提供给第三方小程序进行展示和使用。
插件开发者可以像开发小程序一样编写一个插件并上传代码,在插件发布之后,其他小程序方可调用。小程序平台会托管插件代码,其他小程序调用时,上传的插件代码会随小程序一起下载运行。
小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台状态的小程序切换到前台,这个过程就是热启动;冷启动指的是用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动。
小程序进入「后台」状态一段时间后(目前是 5 秒),微信会停止小程序 JS 线程的执行,小程序进入「挂起」状态。此时小程序的内存状态会被保留,但开发者代码执行会停止,事件和接口回调会在小程序再次进入「前台」时触发。
当开发者使用了后台音乐播放、后台地理位置等能力时,小程序可以在「后台」持续运行,不会进入到「挂起」状态
如果用户很久没有使用小程序,或者系统资源紧张,小程序会被「销毁」,即完全终止运行。具体而言包括以下几种情形:
小程序冷启动时如果发现有新版本,将会异步下载新版本的代码包,并同时用客户端本地的包进行启动,即新版本的小程序需要等下一次冷启动才会应用上。 如果需要马上应用最新版本,可以使用 wx.getUpdateManager API 进行处理。
主要的优化策略可以归纳为三点:
由于小程序的逻辑层和视图层是两个独立的运行环境、分属不同的线程或进程,不能直接进行数据共享,需要进行数据的序列化、跨线程/进程的数据传输、数据的反序列化,因此数据传输过程是异步的、非实时的。
iOS/iPadOS/MacOS 上,数据传输是通过 evaluateJavascript 实现的,还会有额外 JS 脚本解析和执行的耗时。 数据传输的耗时与数据量的大小正相关,如果对端线程处于繁忙状态,数据会在消息队列中等待。
参考链接:https://developers.weixin.qq.com/community/develop/article/doc/00008efe5780d8582ef73dcc15b813 https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips/runtime_setData.html https://developers.weixin.qq.com/miniprogram/dev/framework/runtime/operating-mechanism.html https://developers.weixin.qq.com/community/develop/article/doc/0008a4c4f28f30fe3eb863b2750813
The text was updated successfully, but these errors were encountered:
No branches or pull requests
小程序与普通网页的区别
小程序的架构
为了能够兼顾体验好和在线版本更新,小程序采用了客户端原生技术与web技术结合的混合技术(简称Hybrid技术)来渲染,这么做有以下好处:
架构图解
小程序的渲染层和逻辑层分别由2个线程管理:视图层的界面使用了WebView进行渲染,逻辑层采用JsCore线程运行JS脚本。
那为什么要这样设计呢,前面也提到了管控和安全,为了解决这些问题,我们需要阻止开发者使用一些API,例如浏览器的window对象,跳转页面、操作DOM、动态执行脚本的开放性接口。
逻辑层只提供纯JavaScript的解释执行环境,没有任何浏览器相关接口。
小程序双线程模型各模块功能:
逻辑层:创建一个单独的线程去执行JavaScript,在这里执行的都是有小程序业务逻辑的代码,负责逻辑处理、数据请求、接口调用等
视图层:界面渲染相关的任务都在WebView线程里执行,通过逻辑层代码去控制渲染哪些界面。一个小程序存在多个界面,所以视图层存在多个WebView线程
JSBridge起到架起上层开发与Native(系统层)的桥梁,使得小程序可通过API使用原生的功能,且部分组件为原生组件实现,从而有良好体验
双线程通信
把开发者的JS逻辑代码放到单独的线程去运行,但在WebView线程里,开发者没法直接操作DOM。
那如何实现动态更新页面呢?
如上图所示,逻辑层和视图层的通信会由微信客户端(下文中会采用Native来代指微信客户端)做中转,逻辑层发送网络请求也经由Native转发。
所以 DOM 更新也是可以通过数据通信来实现的,Virtual DOM流程大致是:用JS对象模拟DOM树 => 比较两颗虚拟DOM树的差异 => 把差异应用到真正的DOM树上。
如图:
1. 在渲染层把WXML转化为对应的JS对象。
2. 在逻辑层发生数据变更的时候,通过宿主环境提供的setData方法把数据从逻辑层传递到Native,再转发到渲染层。
3. 经过对比前后差异,把差异应用在原来的DOM树上,更新界面。
我们通过把WXML转化为数据,通过Native进行转发,来实现逻辑层和渲染层的交互和通信。
小程序的能力需要Native来支撑,而这离不开小程序基础库
小程序基础库
小程序的基础库可以被注入到视图层和逻辑层运行,主要用于以下几个方面:
- 在视图层,提供各类组建页面的元素
- 在逻辑层,提供各类API来处理各种逻辑
- 处理数据绑定、组件系统、事件系统、通信系统等一系列框架逻辑
- 自定义组件和插件
所以我们可以看到,小程序的基础库主要包括:
小程序的基础库不会被打包在某个小程序的代码包里边,他会被提前内置在微信客户端。
这样做的好处:
Exparser 框架
Exparser 是微信小程序的组件组织框架,内置在小程序基础库中,为小程序的各种组件提供基础的支持。小程序内的所有组件,包括内置组件和自定义组件,都由Exparser组织管理。
Exparser的主要特点包括以下几点:
基于这个框架,内置了一套组件,以涵盖小程序的基础功能,便于开发者快速搭建出任何界面。同时也提供了自定义组件的能力,开发者可以自行扩展更多的组件,以实现代码复用。
内置组件
小程序基于Exparser框架,内置了一套组件,提供了视图容器类、表单类、导航类、媒体类、开放类等几十种组件
内置组件在小程序框架里的定义是:在小程序架构里无法实现或者实现不好某类功能,使用组件内置到小程序框架里。
常见组件有:
###API
宿主环境提供了丰富的API,可以很方便的调起微信提供的能力。
小程序提供的API按照功能主要分为几大类:网络、媒体、文件、数据缓存、位置、设备、界面、界面节点信息还有一些特殊的开放接口。
需要注意API调用大多数都是异步的。
###自定义组件
自定义组件是开发者可以自行扩充的组件。开发者可以将常用的节点树结构提取成自定义组件,实现代码复用。
在使用自定义组件的小程序页面中,Exparser 将接管所有的自定义组件注册与实例化。以 Component 为例:
Page 构造器的大体运行流程与之相仿,只是参数形式不一样。这样每个页面就有一个与之对应的组件,称为“页面根组件”。
在初始化页面时,Exparser 会创建出页面根组件的一个实例,用到的其他组件也会响应创建组件实例(这是一个递归的过程)。
插件
插件是对一组 js 接口、自定义组件或页面的封装,用于嵌入到小程序中使用。
插件不能独立运行,必须嵌入在其他小程序中才能被用户使用;而第三方小程序在使用插件时,也无法看到插件的代码。因此,插件适合用来封装自己的功能或服务,提供给第三方小程序进行展示和使用。
插件开发者可以像开发小程序一样编写一个插件并上传代码,在插件发布之后,其他小程序方可调用。小程序平台会托管插件代码,其他小程序调用时,上传的插件代码会随小程序一起下载运行。
运行机制
小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台状态的小程序切换到前台,这个过程就是热启动;冷启动指的是用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动。
挂起
小程序进入「后台」状态一段时间后(目前是 5 秒),微信会停止小程序 JS 线程的执行,小程序进入「挂起」状态。此时小程序的内存状态会被保留,但开发者代码执行会停止,事件和接口回调会在小程序再次进入「前台」时触发。
当开发者使用了后台音乐播放、后台地理位置等能力时,小程序可以在「后台」持续运行,不会进入到「挂起」状态
小程序销毁
如果用户很久没有使用小程序,或者系统资源紧张,小程序会被「销毁」,即完全终止运行。具体而言包括以下几种情形:
更新机制
小程序冷启动时如果发现有新版本,将会异步下载新版本的代码包,并同时用客户端本地的包进行启动,即新版本的小程序需要等下一次冷启动才会应用上。 如果需要马上应用最新版本,可以使用 wx.getUpdateManager API 进行处理。
性能优化
主要的优化策略可以归纳为三点:
setData过程
setData 数据通信
由于小程序的逻辑层和视图层是两个独立的运行环境、分属不同的线程或进程,不能直接进行数据共享,需要进行数据的序列化、跨线程/进程的数据传输、数据的反序列化,因此数据传输过程是异步的、非实时的。
常见的 setData 操作错误
参考链接:https://developers.weixin.qq.com/community/develop/article/doc/00008efe5780d8582ef73dcc15b813
https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips/runtime_setData.html
https://developers.weixin.qq.com/miniprogram/dev/framework/runtime/operating-mechanism.html
https://developers.weixin.qq.com/community/develop/article/doc/0008a4c4f28f30fe3eb863b2750813
The text was updated successfully, but these errors were encountered: