小程序原理

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

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

浏览器运行环境

浏览器主要组件包括

  • 用户界面(User Interface)
    地址栏、前进后退按钮、书签菜单等
  • 浏览器引擎(Browser Engine)
    在用户界面和呈现引擎之间传递指令
  • 呈现引擎(Renderering Engine)
    负责显示请求的内容
  • JavaScript解释器
    用于解释和执行JavaScript代码
  • 网络(Networking)
    用于网络调用,比如HTTP请求,其接口与平台无关并为所有平台提供实现。
  • 数据存储(Data Persistence)
    数据持久层,浏览器在本地磁盘上保存的数据。比如Cookie、网络数据库等。
  • 用户界面后端(UI Backend)
    用于绘制基本的窗口组件,比如组合框和窗口。
浏览器组件结构

通常而言浏览器运行在一个进程中,Google Chrome比较特殊每个标签都是一个独立的进程。浏览器是多线程的,重要的线程包括

  • 呈现引擎(渲染引擎):运行在UI线程中
  • JS解释器(JS解释引擎):运行在JS引擎线程中

浏览器中UI渲染线程和JS引擎线程是互斥的,当JS引擎线程执行时UI渲染引擎线程会被挂起,UI更新时会被保存在一个队列中等到JS引擎线程空闲时会立即被执行。

小程序与网页开发

  • 网页开发
    网页开发渲染线程和脚本线程是互斥的,网页开发使用浏览器暴露的DOM API进行DOM选中操作,网页开发者面对的环境是各种浏览器。
  • 小程序
    小程序的渲染层和逻辑层是分开运行在不同的线程中,逻辑层运行在JSCore中因此没有一个完整的浏览器对象,因而缺少DOM API和BOM API。JSCore和NodeJS环境不同,NPM包在小程序中无法运行。小程序开发需面对iOS和Android两大操作系统。

小程序与H5页面区别

  • 运行环境
    小程序是基于浏览器内核重构的内置解析器,H5的宿主环境是浏览器。所以小程序中没有DOM和BOM相关的API,jQuery和NPM包无法在小程序中使用。
  • 系统权限
    小程序能够获得更多的系统权限,比如网络通信状态、数据缓存能力等。
  • 渲染机制
    小程序的逻辑层和渲染层是分开的,H5页面UI渲染跟JS脚本执行都在一个单线程中而互斥,因此H5页面中长时间的脚本执行会导致页面失去响应。

小程序和Web页面对比

  • 静态UI界面差别不大
  • Web页面交互存在卡顿不如原生顺畅
  • Web页面切换生硬不如原生流畅
  • Web页面加载存在白屏不如原生体验好

导致这些问题的主要原因是因为Web页面是基于DOM,在生成和操作DOM耗时且耗性能,另外浏览器对于网页渲染都是单线程处理的方式,包括布局、渲染、JS执行(阻塞)、图像解码等。浏览器重绘时页面刷新频率为60FPS,即16ms/frame,如果16毫秒内不能完成DOM操作就会出现跳帧。Web页面没有GPU图形加速页导致UI界面不流畅。因此,现在的Vue、React等前端框架都推崇使用虚拟DOM,以间接地减少DOM操作频率。

小程序运行环境

小程序开发面对的是iOS和Android微信客户端和辅助开发小程序的开发工具,这三种运行环境的区别在于:

运行环境渲染层逻辑层
iOSWKWebViewJavaScriptCore
AndroidX5浏览器X5 JSCore
小程序开发工具Chrome WebViewNWJS

小程序框架分层

小程序的框架包括两部分分别是View渲染层和AppService逻辑层

小程序原理
  • 渲染层
    View层用来渲染页面结构,渲染层界面使用WebView进行渲染,一个小程序存在多个界面所以渲染层存在多个WebView线程。
  • 逻辑层
    逻辑层采用JSCore线程运行JS脚本,进行逻辑处理、数据请求、接口调用等。
    逻辑层会将数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层进行业务处理。

视图层和逻辑层分别在两个WebView进程中运行,视图层和逻辑层通过系统层的JSBridge进行通信,逻辑层将数据变化通知到视图层,触发视图层页面更新,视图层将触发的事件通知到逻辑层进行业务处理。

小程序的这两个线程的通信经由客户端进行中转,逻辑层把数据变化通知到渲染层,触发渲染层面更新,渲染层把触发的事件通知到逻辑层进行业务处理。

小程序的UI视图和逻辑处理使用多个WebView实现,逻辑处理的JS代码会全部加载到一个WebView中称之为AppService,整个小程序只有一个且整个生命周期常驻内存,所有的视图(WXML和WXSS)都是单独的WebView来承载即AppView。所以一个小程序打开时至少存在2个WebView进程,正是因为每个视图都是一个而独立的WebView进程,考虑到性能消耗,小程序不允许打开超过5层级的页面,同时也是为了更好的体验。

对于AppService可理解为一个页面主要功能是负责逻辑处理部分的执行,底层提供了一个WAService.js文件来提供API接口,接口主要是消息通信封装的WeixinJSBridge。

小程序线程模型

双线程模型

小程序的渲染层和逻辑层分别由两个线程进行管理,小程序运行时有两个线程分别是View视图线程和AppService逻辑线程,这两个线程是相互隔离的,通过桥接协议WeixinJsBridge进行通信。

  • 逻辑层
    界面渲染相关任务在WebView线程中执行,一个小程序可以存在多个界面,所以渲染层存在多个WebView线程。
  • 逻辑层
    逻辑层采用JsCore线程运行JS脚本
线程模块代码原理备注
View视图层,可多个WXML/WXSSWebView渲染WXML编译器把WXML文件转化为JS,构建Virtual DOM。
AppService逻辑层,仅一个JSJsCore运行无法访问window/document对象

小程序的视图层线程和逻辑层线程是如何进行数据传递的呢?

通过两边提供的evaluateJavascript实现,即用户传输的数据需将其转换为字符形式传递,同时把转换后的数据内容拼接成为一份JS脚本,再通过执行JS脚本的形式传递到两边独立的环境中。也就是说,两个线程是通过系统层的WeixinJsBridge来通信的,逻辑层把数据变化通知到视图层,触发视图层页面更新,视图层把触发的事件通知到逻辑层今昔那个业务处理。

页面渲染的具体流程是在渲染层宿主环境会将WXML转化为对应的JS对象,在逻辑层发生数据变更时需通过宿主环境提供的setData方法将数据从逻辑层传递到渲染层,对比前后差异后将差异应用到原来的DOM树上,以渲染出正确的UI界面。

渲染流程

小程序双线程模型与Web前端框架不同之处在于,小程序双线程模型可以更好地管控和提供更加安全的环境,缺点是带来无处不在的异步问题,因为任何数据传输都是线程间通信,也就存在一定的延迟,不过小程序在框架层面已经封装了异步带来的时序问题。

小程序框架

小程序框架

从下往上看,小程序的解析顺序

  1. 最底层是微信,当开发版式小程序开发工具会把代码和框架一起进行打包,微信中打开小程序时微信会将打包好的代码下载到微信App中,这样就可以像在开发工具里一样在微信中运行小程序。
  2. native层是小程序的框架,框架封装了UI层组件和逻辑层组件,这些组件可以通过微信App提供的接口调用手机硬件信息。
  3. 最上层是需进行操作的视图层和逻辑层,视图层和逻辑层的交互式通过数据经由native层进行交互的,视图层和逻辑层可调用native框架中封装好的组件和方法。

小程序生命周期

小程序生命周期可分为应用生命周期和页面生命周期两部分

  • 应用生命周期
  1. 用户首次打开小程序会触发onLaunch事件,全局只触发一次。
  2. 小程序初始化完成后会触发onShow事件,监听小程序显示。
  3. 小程序从前台进入后台会触发onHide事件
  4. 小程序从后台进入前台显示会触发onShow事件
  5. 小程序后台运行一定时间或系统资源占用过高时会被销毁
  • 页面生命周期
  1. 小程序注册完成后会加载页面并触发onLoad事件方法
  2. 页面载入后会触发onShow事件方法而显示页面
  3. 首次显示页面会触发onReady方法,渲染页面元素和样式,一个页面只会调用一次。
  4. 当小程序后台运行或跳转到其它页面时会触发onHide事件方法
  5. 当小程序由后台进入到前台运行或重新进入页面时会触发onShow方法
  6. 当使用重定向wx.redirectTo()方法或关闭当前页面返回上一页wx.navigateBack()方法时会触发onUnload事件方法。

小程序组件系统

小程序的基本组件是基于Exparser框架的,Exparser基于WebComponents的ShadowDOM模型,不依赖浏览器的原生支持,可在纯JS环境中运行。小程序所有节点树操作都依赖于Exparser,包括WXML到页面最终节点树的构建,CreateSelectorQuery调用、自定义组件特性等。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值