微信小程序底层原理剖析

微信小程序底层原理剖析


随着前端技术的不断演进,目前市面上的移动端产品有像大前端转换的趋势。开发一个产品主流上大致有5种开发模式,包括 Native APP 原生应用、WebAPP 网页应用、Hybrid App 混合式开发、ReactNative、轻应用小程序。开发一款 APP,如果注重性能,不需要过多的动态内容,可以选择原生应用来开发。如果性能要求不高,只是需要点开即用,那么 WebAPP 即可满足。如果这两种要求都必须满足,那么 Hybrid App 混合式的开发是一种折中的方法,将两者优势互补,满足大部分的需求。近几年,出现了类似 ReactNative 和小程序这种深度定制的开发模式,开发只需要写 Javascript 就可以产出性能可与原生媲美的产品,通过脚本语言面向开发者,实际跑的确是的原生组件。小程序也好,其他框架也好,理解他们的设计缘由、实现原理,还是能学到很多很多东西的。

从两大线程说开

小程序由两大线程组成:负责界面的线程(view thread)和服务线程(appservice thread),各司其职由互相配合。两个线程分别用于渲染层和逻辑层,渲染层的界面使用了 WebView 进行渲染,通过逻辑层代码去控制渲染哪些界面,如果一个小程序存在多个界面,则渲染层存在多个 WebView 线程;逻辑层采用一个单独的 JsCore 线程运行 JS 脚本,在这个环境下执行的都是有关小程序业务逻辑的代码。套用一张官方的图来解释。

为什么要这么设计呢?主要还是处于管控和安全上的考虑。我们需要阻止开发者使用一些浏览器提供的,诸如跳转页面、操作 DOM、动态执行脚本的开放性接口。

小程序的生命周期

小程序的生命周期借鉴了Android的生命周期,如果你了解过Android的APP开发,那么理解小程序的就会很简单。

界面线程有四大状态:

  1. 初始化状态:初始化界面线程所需要的工作,包括工作机制,基本和我们开发者没有关系,等初始化完毕就向“服务线程”发送初始化完毕信号,然后进入等待传回初始化数据状态。

  2. 首次渲染状态:收到“服务线程”发来的初始化数据后(就是 json和js中的data数据),就开始渲染小程序界面,渲染完毕后,发送“首次渲染完毕信号”给服务线程,并将页面展示给用户。

  3. 持续渲染状态:此时界面线程继续一直等待“服务线程”通过this.setdata()函数发送来的界面数据,只要收到就重新局部渲染,也因此只要更新数据并发送信号,界面就自动更新。

  4. 结束状态:结束渲染。

服务线程五大状态:

  1. 初始化状态:无需和其他模块交流,跟小程序开发也没多大关联,此阶段就是启动服务线程所需的基本功能,比如信号发送模块。系统的初始化工作完毕,就调用自定义的onload和onshow,

然后等待界面线程的“界面线程初始化完成”信号。

onload是只会首次渲染的时候执行一次,onshow是每次界面切换都会执行,简单理解,这就是唯一差别。

  1. 等待激活状态:接收到“界面线程初始化完成”信号后,将初始化数据发送给“界面线程”,等待界面线程完成初次渲染。

  2. 激活状态:收到界面线程发送来的“首次渲染完成”信号后,就进入激活状态既程序的正常运行状态,并调用自定义的onReady()函数。

此状态下就可以通过 this.setData 函数发送界面数据给界面线程进行局部渲染,更新页面。

  1. 后台运行状态:如果界面进入后台,服务线程就进入后台运行状态,从目前的官方解读来说,这个状态挺奇怪的,和激活状态是相同的,也可以通过setdata函数更新界面的。毕竟小程序的框架刚推出,应该后续会有很大不同吧。

小程序双线程间的通信

把开发者的 JS 逻辑代码放到单独的线程去运行,但在 Webview 线程里,开发者就没法直接操作 DOM。那要怎么去实现动态更改界面呢?

前面我们知道,逻辑层和渲染层的通信会由 Native (微信客户端)做中转,逻辑层发送网络请求也经由 Native 转发。这是不是意味着,我们可以把 DOM 的更新通过简单的数据通信来实现呢?

Virtual DOM 相信大家都已有了解,大概是这么个过程:用JS对象模拟DOM树 -> 比较两棵虚拟DOM树的差异 -> 把差异应用到真正的DOM树上。

在这里我们可以用上,如图:

  1. 在渲染层把 WXML 转化成对应的 JS 对象。

  2. 在逻辑层发生数据变更的时候,通过宿主环境提供的 setData 方法把数据从逻辑层传递到 Native,再转发到渲染层。

  3. 经过对比前后差异,把差异应用在原来的 DOM 树上,更新界面。

我们通过把 WXML 转化为数据,通过 Native 进行转发,来实现逻辑层和渲染层的交互和通信。而这样完整的一套框架,基本上都是通过小程序的基础库来完成的。

小程序的基础组件

native层就是小程序的框架,就像常用的react框架一样,这个框架里封装了ui层组件和逻辑层组件,这些组件可以通过微信app提供的接口调用手机硬件信息

这些基础组件库是JavaScript编写的,它可以被注入到渲染层和逻辑层运行。主要用于:

  • 在渲染层,提供各类组件来组件页面的元素

  • 在逻辑层,提供各种API来处理各种元素。

  • 处理数据绑定、组件系统、事件系统、通信系统等一系列框架逻辑

由于小程序的渲染层和逻辑层是两个线程管理,两个线程各自注入了基础库。小程序的基础库不会被打包在某个小程序的代码包里边,它会被提前内置在微信客户端。

总结

小程序考虑到了原生开发和纯web开发的不利之处:用纯客户端原生技术来编写小程序 的话,小程序代码需要与微信代码一起编包,显然过于繁重了;而用纯 Web 技术来渲染小程序,在一些有复杂交互的页面上可能会面临一些性能问题。

因此,小程序选择了 Hybrid 的渲染方式,将UI渲染跟 JavaScript 的脚本执行分在了两个线程,巧妙了解决了上述问题,作为一种全新的前端开发框架能够很快成为许多开发者的最爱也就不足为奇了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354