小程序原理初探

2021-01-14 15:09:49 浏览数 (1)

微信小程序是介于Native和web app之间的产物。它依托浏览器(webview)展示,同时可以调用原生能力(如获取通信录,拍照等等),同一份代码可运行在Android,iOS和微信调试开发工具内(跨平台能力)。

与RN的跨平台不同,小程序大部分UI组件并不是原生渲染,还是类似web app用浏览器渲染。只有少量组件是Native实现(Native组件层在WebView层之上): <canvas/> <video/> <map/> <textarea/>

那么,小程序和web app有什么区别呢?仅仅只是能够通过JsBridage调用Native能力的区别吗?

答案:No!No!No!

相信每位学习小程序的同学都看过Page生命周期这节,图中有『View Thread』和『AppService Thread』两个线程图。为什么有两个线程?每个线程处理什么?和webview的关系如何?

为了更好的了解的真相,让我们先温习下浏览器如何运行,如何展示UI。

浏览器运行环境

首先,浏览器的主要组件有:

  • 用户界面(User Interface) - 地址栏、前进/后退按钮、书签菜单等(除了浏览器主窗口外,其他显示的各个部分都属于用户界面)。
  • 浏览器引擎(Browser engine) - 在用户界面和呈现引擎之间传送指令。
  • 呈现引擎(Rendering engine) important- 负责显示请求的内容(如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上)。
  • JavaScript 解释器(JavaScript Interpreter)important - 用于解析和执行 JavaScript 代码。
  • 网络(Networking) - 用于网络调用,比如 HTTP 请求。其接口与平台无关,并为所有平台提供底层实现。
  • 数据存储(Data Persistence)。这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是一个完整(但是轻便)的浏览器内数据库。
  • 用户界面后端(UI Backend) - 用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。

参考下图:

browser.png

一般来说,浏览器运行在一个进程中(但是chrome比较特殊,每个标签页都是一个独立进程)。同时,浏览器是多线程的,比较重要的线程有:

  • 呈现引擎(又称为渲染引擎):运行在UI线程中。
  • JavaScript 解释器(又称为JS解析引擎):运行在JS引擎线程中。

注意:UI 渲染线程与 JavaScript 引擎线程为互斥的关系,当 JavaScript 引擎线程执行时 UI 渲染线程会被挂起,UI 更新会被保存在一个队列中等到 JavaScript 引擎线程空闲时立即被执行。

小程序运行环境

小程序运行时会有两个线程:『View Thread』和『AppService Thread』,相互隔离,通过桥接协议WeixinJsBridage进行通信(包括 setData 调用、canvas指令和各种DOM事件)

下述表格展示了两个线程的区别:

线程名称

所属模块

运行代码

原理

备注

View

视图层(可能有多个)

WXML/WXSS

webview渲染

wxml编译器把wxml文件转为js(构建virtual dom);wxss编译器把wxss文件转化为js

AppService

逻辑层(一个)

JS

JavascriptCore运行

无法访问 window/document对象

两个线程直接如何进行数据传递?可参考微信官方说明:

通过两边提供的 evaluateJavascript 所实现。即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境

也就是说,两个『模块/线程』是通过系统层的JSBridage来通信的,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理。可参考下图:

weixin-thread.jpg

所以可以得出如下结论:

  • 小程序js代码无法操作DOM对象,也无法直接操作wxml上的容器或组件(js代码和webview没有运行在同一个线程中)
  • 如果需要在View Thread中运行自定义js代码,可以使用wxs(微信开发的脚本语言),它和View同一个线程。

js引擎

平台

渲染

js运行环境

iOS

WKWebView渲染(环境有 iOS8、iOS9、iOS10)

JavaScriptCore

Android

X5 基于 Mobile Chrome 37 内核来渲染

X5 JSCore来解析

开发工具

Chrome Webview 渲染

nwjs 中

小结

虽然目前小程序使用 webview 渲染,但是不意味着它以后也一直使用webview渲染。作为开发者,只能依赖小程序提供的环境。而这个环境再下层如何处理,并不受开发者控制,这意味小程序未来很可能全面采用原生渲染,类似RN或Weex,毕竟,原生的UI体验更好。

参考文章

  • https://hijiangtao.github.io/2018/01/08/JavaScript-and-Browser-Engines-with-Threads/
  • https://juejin.im/entry/58842a4a128fe10068336681

0 人点赞