谈谈微信小程序的双线程模型

WebView是属于单线程模型,页面的渲染和JavaScript逻辑运算都是运行在WebView中,而微信小程序是使用双线程模式,就是渲染层和逻辑层分开。

渲染层和逻辑层

在微信的文档可以看到这么一段话,小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端(下文中也会采用Native来代指微信客户端)做中转,逻辑层发送网络请求也经由Native转发,小程序的通信模型下图所示。

理解WebView的单线程模式

在理解双线程模式前我们先来理解WebView的单线程模型,浏览器为每一个window分配一个线程用于执行JavaScript,每一时刻只会有一段JS代码在执行,那么在JavaScript实现ajax网络请求是不是异步的呢,虽然window是单线程,但是浏览器并不是单线程的,浏览器是基于事件驱动的,每一个window都有一个Event Loop,比如鼠标点击事件发生、定时器触发事件、XMLHttpRequest 回调都会放入执行队列,队列就会按照顺序执行事件,而其中的XMLHttpRequest网络请求实际上是浏览器新开了一个线程执行,把结果回调放入队列。

小程序双线程模式

WebView的逻辑运算和页面渲染都是在同一个线程上,而微信小程序的渲染层还是运行在WebView,把JavaScript运行在JavaScript引擎,在Android是运行在V8引擎,而在iOS是运行在JavaScriptCore。

界面的渲染过程

WebView是使用HTML+CSS生成DOM,然后渲染到WebView,我们可以通过JS对DOM进行操作,修改显示的内容。在微信小程序是使用wxml和wxss描述UI,和HTML、CSS的相对应的,在逻辑层生成虚拟的DOM,然后发送到渲染层,渲染层会根据虚拟的DOM生成真实的DOM,渲染到WebView,但是为了提高性能,不会每一次都重新渲染,而且根据前后虚拟DOM的差异,把差异部分更新到真实的DOM,仅仅渲染这部分Diff。


Hello World

使用特定语言描述

{
    "name":"view",
    "children":[
        {
            "text":"Hello World"
        }
    ]
}

为何使用双线程模型

由于微信小程序定制了专用的DSL,HTML、CSS和JavaScript无法直接运行在小程序,由于使用了双线程模式,也不能直接操作DOM,导致很多前端框架无法使用,这一点是被很多开发者所诟病。那么微信为何要这么设计呢?

使用专用的DSL,加上不允许操作DOM,逻辑和渲染都只能用程序包的代码,意味着无法实现动态更新,对于平台而已,开发者在小程序商店发布小程序是需要受到微信的监控,发布的代码也需要经过自动审查,不允许开发者随意更新代码。

双线程是否会提升性能?

把渲染层和逻辑层分别运行在不同的线程,多了一条线程貌似可以提升性能?实际上并不会,绝大多数的情况下,JS运行的片段耗时都是很短的,比如文件读取、网络请求等都是其它的线程进行,并不会阻塞JS线程,然而UI的更新还需要跨线程发送到WebView中,这个显然是会增加耗时,效率是更加低的。

你可能感兴趣的:(谈谈微信小程序的双线程模型)