小程序的架构和原理

技术选型

小程序在设计之初,首要目标就是快。一般来说,渲染界面的技术有三种:

  1. 用纯客户端原生技术来渲染
  2. 用纯 Web 技术来渲染
  3. Hybrid 技术
    而微信不可能用纯客户端技术把小程序放入微信中,这样小程序代码就会和微信一起打包,跟随微信一起发布版本。
    但是如果用纯 Web 技术来渲染又会造成性能问题,因为 UI 线程和 JS 线程是互斥的。
    考虑微信需要建立一个生态,所以需要对小程序进行管控,所以不希望开发者进行DOM相关操作。所以提供了一个沙箱环境(不提供任何浏览器接口,只提供纯JS的解释器环境)。
    所以自然地 JS 被隔离出来,并且我们还需要通过微信客户端进行 Native 操作,所以这个架构如下:

    WXML 和 WXSS 工作在渲染层(webview),JS脚本工作在逻辑层(jsCore)。并且每个小程序页面都是对应一个 webview 线程,这样性能比较好。

其内部也是通过 virtual dom 进行管理DOM的,当我们调用 setData 后,会重新生成一个新的 virtual dom 进行 diff 比对,然后进行 patch。

最关键的是 setData 发生了什么?

我们发现小程序的组织结构和 Vue 很像,都是使用 template 语法,这样可以降低开发者使用门槛,另一方面却使用类似 React 的 setState 的显示调用更新机制。为什么不使用类似 Vue 一样的直接修改 data 的值呢?
因为小程序的软件架构,视图层是webview线程,逻辑层是jscore线程,并不具备直接通信的通道。所以为了视图层和逻辑层的通信,两边都采用了 evaluateJavascript 来和 Native 层通信,导致了小程序必须得通过显示调用的方式来修改 data 的值,这样才能够通知到 Native 层。evaluateJavascript 只能传字符串,所以我们的 data 中的数据都会进行 JSON.stringify 转义成字符串进行传递。

所以一次完整的用户是

  1. 渲染层 -> Native (点击事件)
  2. Native -> 逻辑层 (点击事件)
  3. 逻辑层 -> Native (setData)
  4. Native -> 渲染层 (setData)

可以看到通信一次是比较麻烦且耗时,虽然 setData 的设计和 React 类似,但是内部却是不同的,React 是异步在下一个时间节点合并 setState 然后进行 state 的处理,属于是异步。而 setData 的修改和 Vue 的机制类似,是对 data 进行同步的更新,但是对于渲染层的改变却是异步的。

既然双线程的架构比较耗时,那在一些强交互场景下是就势必要引入原生组件了。
这样可以绕过 setData 了,提高渲染性能,也可以扩展 web 能力,比如输入框的 focus 状态下可以更方便的控制键盘。

另外需要注意的是,不要对 data 设置为 undefined,容易造成不必要的问题。因为 undefined 在 JSON.stringify 后是不会传递过去的。

更新机制

小程序启动会有两种情况,一种是「冷启动」,一种是「热启动」。

  • 热启动:假如用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时无需重新启动,只需将后台态的小程序切换到前台,这个过程就是热启动;
  • 冷启动:用户首次打开或小程序被微信主动销毁后再次打开的情况,此时小程序需要重新加载启动,即冷启动。

小程序没有重启的概念。

未启动时更新

开发者在管理后台发布新版本的小程序之后,如果某个用户本地有小程序的历史版本,此时打开的可能还是旧版本。微信客户端会有若干个时机去检查本地缓存的小程序有没有更新版本,如果有则会静默更新到新版本。总的来说,开发者在后台发布新版本之后,无法立刻影响到所有现网用户,但最差情况下,也在发布之后 24 小时之内下发新版本信息到用户。用户下次打开时会先更新最新版本再打开。

启动时更新

小程序每次冷启动时,都会检查是否有更新版本,如果发现有新版本,将会异步下载新版本的代码包,并同时用客户端本地的包进行启动,即新版本的小程序需要等下一次冷启动才会应用上。
如果需要马上应用最新版本,可以使用 wx.getUpdateManager API 进行处理。

在发布小程序之后,小程序是一个热更新机制,会定时 check 是否有新版本,异步下载最新代码并进行版本替换,通常在 24小时 内进行全部的版本替换。

也可以开发者在业务代码中来监听是否有新版本,给一个 wx.showModal 来提示用户从而进行强制更新。

https://developers.weixin.qq.com/community/develop/doc/000c2430d30b70251e86f0a0256c09?highLine=%E5%AE%9A%E6%97%B6check%E6%96%B0%E7%89%88%E6%9C%AC

https://developers.weixin.qq.com/miniprogram/dev/framework/runtime/update-mechanism.html

官方推荐的做法热更新,如果是必要的更新,才会推荐使用弹窗强制更新。

你可能感兴趣的:(js)