小程序分为:逻辑层jsCore和渲染层webview
一、小程序逻辑层 App Service(APP服务)
逻辑层也称之为 App Service。
缘由:
开发者写的所有代码最终将会打包成一份 JavaScript 文件,并在小程序启动的时候运行,直到小程序销毁,这一行为类似 ServiceWorker。
顺序梳理:
逻辑层jsCore—也可称为App Service—类似于Service Worker —它的本质是Web Worker(为 JavaScript 创造多线程环境)
二、ServiceWorker
本质:
Service Worker 是一种 Web Worker。它本质上是一个与主浏览器线程分开运行的 JavaScript 文件,可以拦截网络请求、缓存资源或从缓存中检索资源、传递推送消息。
作用:
由于 Workers 与主线程分开运行,因此 Service Worker 独立于与其关联的应用程序。这将导致以下结果:
(1)当应用程序处于没有活动状态时,Service Worker 可以从服务器接收推送消息。这可以让应用程序向用户显示推送通知,即使它未打开,WebApp。
注意:浏览器在没有运行的情况下是否能收到通知取决于浏览器如何与操作系统集成。
(2)Service Worker 不能直接访问 DOM
生命周期:
安装 Service Worker,需要在 JavaScript 主进程中进行注册。
注册完毕后,便会开始激活加载相关事件。
使用完毕后销毁。
三、web worker
简介:
当在 HTML 页面中执行脚本时,页面状态是不可响应的,直到脚本完成。
web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。
您可以继续做任何愿意做的事情:点击、选取内容等等,而此时H5的 web worker 在后台运行。
浏览器支持:
所有主流浏览器均支持 web worker,除了 Internet Explorer。
通俗理解:
web worker 是运行在后台的 JavaScript,不会影响页面的性能
作用:就是为 JavaScript 创造多线程环境
允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。
注意:
Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。
这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。
四、逻辑层 App Service:
在 JavaScript 的基础上,增加了一些功能,以方便小程序的开发:
(1)增加 App({}) 和 Page({}) 方法,进行程序注册和页面注册。
(2)增加 getApp 和 getCurrentPages 方法,分别用来获取 App 实例和当前页面栈,至于实例与页面栈,后续会一一介绍。
(3)提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
(4)提供模块化能力,每个页面有独立的作用域。
注意:
小程序框架的逻辑层并非运行在浏览器中,因此 JavaScript 在 web 中一些能力都无法使用,如 window,document 等。
缘由:
小程序逻辑层的行为类似 ServiceWorker,而ServiceWorker的本质是一种 Web Worker,它本质上是一个与主浏览器线程分开运行的 JavaScript 文件。由于 web worker 位于外部文件中,所以无法访问相关BOM和DOM。
五、程序与页面
从逻辑组成来说,一个小程序是由多个“页面”组成的“程序”。
逻辑组成上分为小程序级别和页面级别,所以小程序的生命周期也可以分为:程序生命周期和页面生命周期。
六、程序构造/注册器App()
App注册:小程序加载时首先在入口文件 app.js 中调用 App 方法进行注册,绑定生命周期回调函数、错误监听和页面不存在监听函数等。
注册小程序:App()方法,所以App方法也被称为程序构造器或者程序注册器。
获取程序构造/注册器getApp():
宿主环境提供了 App() 构造器用来注册一个程序App,App() 构造器必须写在项目根目录的入口文件app.js里。
那在其他JS脚本中可以使用宿主环境提供的 getApp() 来获取程序实例。
小程序全局数据:
小程序的JS脚本是运行在JsCore的线程里(只有一个)。
小程序的每个页面各自有一个WebView线程进行渲染。
但是小程序切换页面时,小程序逻辑层的JS脚本运行上下文依旧在同一个JsCore线程中。
共享全局数据:
因为小程序逻辑层的JS脚本运行上下文始终在同一个JsCore线程中。
因此不同页面直接可以通过App实例下的属性来共享数据,App构造器可以传递其他参数作为全局属性以达到全局共享数据的目的。
注意:
所有页面的脚本逻辑都跑在同一个JsCore线程,页面使用setTimeout或者setInterval的定时器,然后跳转到其他页面时,这些定时器并没有被清除,需要开发者自己在页面离开的时候进行清理。