小程序底层架构剖析

当我们前端切图崽网上冲浪的时候,会发现有很多技术文章都在分析vue框架,react框架,显少有分析小程序框架的 。那今天就通过这篇短小精悍的文章带大家了解一下微信小程序的底层架构 。(如无特殊说明,下文中提到的小程序都是微信小程序)
小程序的由来我们先抛出一个问题,在没有小程序的时候,企业们都在微信里怎么运营? 答案就是小程序的“前身”-公众号,企业们普遍会把H5网站放在公众号作为流量转换的入口 。但是h5确实让公众号遇到了一些问题 。
【小程序底层架构剖析】首先就是白屏过程,对于一些复杂页面,受限于设备性能和网络速度,白屏会更加明显;再就是缺少操作反馈,比如页面切换生硬以及点击所带来的迟滞感等等;
微信团队内部通过JS-SDK以及后来的增强JS-SDK已经能够解决一些问题,但是对于上述问题是JS-SDK所处理不了的,急需一个全新的系统来完成,它需要具备以下能力:

  • 快速加载
  • 更强大的能力
  • 原生的体验
  • 易用且安全的微信数据开放
  • 高效,简单的开发
于是,小程序诞生了 。
双线程架构此处点题一下,本文我们讨论的是小程序的底层架构,其实,双线程架构就是小程序的核心 。
小程序底层架构剖析

文章插图
那为什么要设计成双线程架构呢?首先我们来回顾一下浏览器的线程模型,浏览器是一个单线程架构,主要原因是js允许访问操作DOM,因此js线程和渲染线程只能互斥运行 。
那小程序又是如何做到双线程的呢,根本原因就是微信小程序禁止js操作DOM 。
使用双线程架构的优势一目了然:
  • 提高用户体验(ui和逻辑分离,避免页面长时间阻塞和卡顿)
  • 优化应用性能(运行在不同的线程中,可以同时渲染或者计算)
  • 开发效率更高(解耦和松散耦合)
接下来就带大家了解一下渲染层以及逻辑层的设计思路 。
设计思路-渲染层标签实现小程序使用的是Exparser组件模型,Exparser组件模型与Web Components中的shadow DOM高度相似,微信为什么使用自定义组件框架,而不使用Web Components呢?主要还是出于安全考虑,并且方便管控 。既然Exparser组件框架与shadow DOM高度相似,那么我们首先来了解一下shadow DOM 。
shadow DOM: Web Components的一个重要属性是封装-可以将标记结构、样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净、整洁 。其中,shadow DOM接口是关键所在,它可以将一个隐藏的,独立的DOM附加到一个元素上 。
小程序底层架构剖析

文章插图
shadow DOM允许将隐藏的DOM树附加到常规的DOM树中-它以shadow root节点为起始根节点,在根节点的下方,可以是任意元素,和普通的DOM一样 。
以上解释来源于MDN,其实shadow DOM并不神秘,像我们非常熟悉的video标签本质上就是用shadow DOM实现的 。我们先打开chrome浏览器设置中的“打开用户代理shadow DOM”,然后再点击video标签就能看到 。
小程序底层架构剖析

文章插图
创建shadow DOM也非常简单,直接使用attachShadow方法就可以创建 。
var shadow = Element.attachShadow({ mode: 'closed'})
  • 1.
Exparser组件模型:Exparser组件模型参考了shadow DOM并进行了一些修改,像事件系统就是完全复刻的,slot插槽,属性传递等都基本一致 。但同时它又具有一些特点:
  • 基于shadow DOM模型:模型上与Web Components的shadow DOM高度相似,但不依赖浏览器的原生支持,也没有其他依赖库;实现时,还针对性地增加了其他API以支持小程序组件编程;
  • 可在纯JS环境中运行:这意味着逻辑层也具有一定的组件树组织能力;
  • 高效轻量:性能表现好,在组件实例极多的环境下表现尤其优异,同时代码尺寸也较小;
WXML编译了解了小程序的组件系统之后,接下来看看WXML的编译过程 。小程序中的DOM编译流程与vue类似,也会先将代码字符串编译为虚拟DOM,小程序中的虚拟DOM结构如下:WXML最终会被编译为JS文件,然后插入到渲染层的script标签中 。


推荐阅读