浅析微信小程序的底层架构原理_第1页
浅析微信小程序的底层架构原理_第2页
浅析微信小程序的底层架构原理_第3页
浅析微信小程序的底层架构原理_第4页
浅析微信小程序的底层架构原理_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

浅析微信⼩程序的底层架构原理⼀、⼩程序基础知识⼩程序是基于WEB规范,采⽤HTML、CSS和JS等搭建的⼀套框架,微信官⽅给它们取的名字:WXML、WXSS,但本质上还是在整个WEB体系之下构建的。WXML说到底就是xml的⼀个⼦集。WXML采⽤微信⾃定义的少量标签WXSS,⼤家可以理解为就是⾃定义的CSS。实现逻辑部分的JS还是通⽤的ES规范,并且runtime还是Webview(IOSWKWEBVIEW、ANDROIDX5)1、⼩程序的组成结构⼀个完整的⼩程序主要由以下⼏部分组成:⼀个⼊⼝⽂件:app.js⼀个全局样式:app.wxss⼀个全局配置:app.json页⾯:pages下,每个页⾯再按⽂件夹划分,每个页⾯4个⽂件(1)视图层:wxml,wxss(2)逻辑层:js,json(页⾯配置,不是必须)注:pages⾥⾯还可以再根据模块划分⼦⽬录,孙⼦⽬录,只需要在app.json⾥注册时填写路径就⾏。2、⼩程序项⽬打包:编辑器它本⾝也是基于WEB技术体系实现的,nwjs+react,nwjs简单是说就是node+webkit,node提供给我们本地api能⼒,⽽webkit提供给我们web能⼒,两者结合就能让我们使⽤JS+HTML实现本地应⽤程序。既然有nodejs,那上⾯的打包选项⾥的功能就好实现了。(1)ES6转ES5:引⼊babel-core的node包(2)CSS补全:引⼊postcss和autoprefixer的node包(postcss和autoprefixer的原理看这⾥)(3)代码压缩:引⼊uglifyjs的node包打包后⽬录结构:

所有的⼩程序基本都最后都被打成上⾯的结构:(1)WAService.js框架JS库,提供逻辑层基础的API能⼒(2)WAWebview.js框架JS库,提供视图层基础的API能⼒(3)WAConsole.js框架JS库,控制台(4)app-config.js⼩程序完整的配置,包含我们通过app.json⾥的所有配置,综合了默认配置型(5)app-service.js我们⾃⼰的JS代码,全部打包到这个⽂件(6)frame.html⼩程序视图的模板⽂件,所有的页⾯都使⽤此加载渲染,且所有的WXML都拆解为JS实现打包到这⾥(7)pages所有的页⾯,这个不是我们之前的wxml⽂件了,主要是处理WXSS转换,使⽤js插⼊到header区域。3、与H5页⾯的区别⼩程序和普通的h5页⾯到底有什么区别呢?(1)运⾏环境:⼩程序基于浏览器内核重构的内置解析器,⽽h5的宿主环境是浏览器。所以⼩程序中没有DOM和BOM的相关API,jQuery和⼀些NPM包都不能在⼩程序中使⽤;普通⽹页开发可以使⽤各种浏览器提供的DOMAPI,进⾏DOM操作,⽽⼩程序的逻辑层和渲染层是分开的,逻辑层运⾏在JSCore中,并没有⼀个完整浏览器对象,因⽽缺少相关的DOMAPI和BOMAPI。(2)系统权限:⼩程序能获得更多的系统权限,如⽹络通信状态、数据缓存能⼒等;(3)渲染机制:⼩程序的逻辑层和渲染层是分开的,⽽h5页⾯UI渲染跟JavaScript的脚本执⾏都在⼀个单线程中,互斥。所以h5页⾯中长时间的脚本运⾏可能会导致页⾯失去响应。普通⽹页开发渲染线程和脚本线程是互斥的,这也是为什么长时间的脚本运⾏可能会导致页⾯失去响应,⽽在⼩程序中,⼆者是分开的,分别运⾏在不同的线程中。此外,⼩程序⾯对的是iOS和Android微信客户端和辅助开发的⼩程序开发者⼯具。根据官⽅⽂档,这三⼤运⾏环境也是有所区别的:所以微信⼩程序介于web端和原⽣App之间,能够丰富调⽤功能接⼝,同时⼜跨平台。⼆、⼩程序架构1、双线程模型微信⼩程序的框架包含两部分:View视图层、AppService逻辑层。View层⽤来渲染页⾯结构,AppService层⽤来逻辑处理、数据它们在两个进程(两个Webview)⾥运⾏。视图层和逻辑层通过系统层的JSBridage进⾏通信,逻辑层把数据变化通知到视图层,触发视图层页⾯更新,视图层把触发的事件通知到逻辑层进⾏业务处理。⼩程序的渲染层和逻辑层分别由2个线程管理:(1)视图层:界⾯渲染相关的任务全都在WebView线程⾥执⾏。⼀个⼩程序存在多个界⾯,所以渲染层存在多个WebView线程。(2)逻辑层:采⽤JsCore线程运⾏JS脚本。视图层和逻辑层通过系统层的WeixinJsBridage进⾏通信:逻辑层把数据变化通知到视图层,触发视图层页⾯更新,视图层把触发的事件通知到逻辑层进⾏业务处理。2、渲染流程把开发者的JS逻辑代码放到单独的线程去运⾏,但在Webview线程⾥,开发者就没法直接操作DOM。那要怎么去实现动态更改界⾯呢?如上图所⽰,逻辑层和试图层的通信会由Native(微信客户端)做中转,逻辑层发送⽹络请求也经由Native转发。这也就是说,我们可以把DOM的更新通过简单的数据通信来实现。VirtualDOM相信⼤家都已有了解,⼤概是这么个过程:⽤JS对象模拟DOM树->⽐较两棵虚拟DOM树的差异->把差异应⽤到真正的DOM树上。页⾯渲染的具体流程是:在渲染层,宿主环境会把WXML转化成对应的JS对象,在逻辑层发⽣数据变更的时候,我们需要通过宿主环境提供的setData⽅法把数据从逻辑层传递到渲染层,再经过对⽐前后差异,把差异应⽤在原来的Dom树上,渲染出正确的UI界⾯。(1)在渲染层把WXML转化成对应的JS对象。(2)在逻辑层发⽣数据变更的时候,通过宿主环境提供的setData⽅法把数据从逻辑层传递到Native,再转发到渲染层。(3)经过对⽐前后差异,把差异应⽤在原来的DOM树上,更新界⾯。我们通过把WXML转化为数据,通过Native进⾏转发,来实现逻辑层和渲染层的交互和通信。3、双线程模型设计的好处双线程模型是⼩程序框架与业界⼤多数前端Web框架不同之处。基于这个模型,可以更好地管控以及提供更安全的环境。缺点是带来了⽆处不在的异步问题(任何数据传递都是线程间的通信,也就是都会有定的延时),不过⼩程序在框架层⾯已经封装好了异步带来的时序问题。为什么要这样设计呢,前⾯也提到了管控和安全,为了解决这些问题,我们需要阻⽌开发者使⽤些,例如浏览器的window对象,跳转页⾯、操作DOM、动态执⾏脚本的开放性接⼝。我们可以使⽤客户端系统的JavaScript引擎(iOS下的JavaScriptCore框架,安卓下腾讯x5内核提供的JsCore环境),这个沙箱环境只提供纯JavaScript的解释执⾏环境,没有任何浏览器相关接⼝,这就是⼩程序双线程模型的由来。三、组件系统我们知道⼩程序是有⾃⼰的组件的,这些基本组件就是基于Exparser框架。Exparser基于WebComponents的ShadowDOM模型,但是不依赖浏览器的原⽣⽀持,⽽且可在纯JS环境中运⾏。1、Exparser框架Exparser是微信⼩程序的组件组织框架,内置在⼩程序基础库中,为⼩程序的各种组件提供基础的⽀持。⼩程序内的所有组件,包括内置组件和⾃定义组件,都由Exparser组织管理。Exparser的主要特点包括以下⼏点:(1)基于ShadowDOM模型:模型上与WebComponents的ShadowDOM⾼度相似,但不依赖浏览器的原⽣⽀持,也没有其他依赖库;实现时,还针对性地增加了其他API以⽀持⼩程序组件编程。(2)可在纯JS环境中运⾏:这意味着逻辑层也具有定的组件树组织能⼒。(3)⾼效轻量:性能表现好,在组件实例极多的环境下表现尤其优异,同时代码尺⼨也较⼩。⼩程序中,所有节点树相关的操作都依赖于Exparser,包括WXML到页⾯最终节点树的构建、createSelectorQuery调⽤和⾃定义组件特性等。2、内置组件基于Exparser框架,⼩程序内置了⼀套组件,提供了视图容器类、表单类、导航类、媒体类、开放类等⼏⼗种组件。有了这么丰富的组件,再配合WXSS,可以搭建出任何效果的界⾯。在功能层⾯上,也满⾜绝⼤部分需求。3、原⽣组件在内置组件中,有⼀些组件并不完全在Exparser的渲染体系下,⽽是由客户端原⽣参与组件的渲染。⽐如说Map组件,它渲染的层级⽐在WebView层渲染的普通组件要⾼。四、运⾏机制(1)启动热启动:假如⽤户已经打开过某⼩程序,然后在⼀定时间内再次打开该⼩程序,此时⽆需重新启动,只需将后台态的⼩程序切换到前台,这个过程就是热启动;冷启动:⽤户⾸次打开或⼩程序被微信主动销毁后再次打开的情况,此时⼩程序需要重新加载启动,即冷启动。⼩程序没有重启的概念当⼩程序进⼊后台,客户端会维持⼀段时间的运状态,超过⼀定时间后(⽬前是5分钟)会被微信主动销毁当短时间内(5s)连续收到两次以上收到系统内存告警,会进⾏⼩程序的销毁(2)销毁只有当⼩程序进⼊后台⼀定时间,或者系统资源占⽤过⾼,才会被真正的销毁。(3)更新机制开发者在后台发布新版本之后,⽆法⽴刻影响到所有现⽹⽤户,但最差情况下,也在发布之后24⼩时之内下发新版本信息到⽤户。⼩程序每次冷启动时,都会检查是否有更新版本,如果发现有新版本,将会异步下载新版本的代码包,并同时⽤客户端本地的包进⾏启动,即新版本的⼩程序需要等下⼀次冷启动才会应⽤上。所以如果想让⽤户使⽤最新版本的⼩程序,可以利⽤wx.getUpdateManager做个检查更新的功能:checkNewVersion(){constupdateManager=wx.getUpdateManager();updateManager.onCheckForUpdate((res)=>{console.log('hasUpdate',res.hasUpdate);//请求完新版本信息的回调if(res.hasUpdate){updateManager.onUpdateReady(()=>{this.setData({hasNewVersion:true});});}});}五、⼩程序的技术实现⼩程序的UI视图和逻辑处理是⽤多个webview实现的,逻辑处理的JS代码全部加载到⼀个Webview⾥⾯,称之为AppService,整个⼩程序只有⼀个,并且整个⽣命周期常驻内存,⽽所有的视图(wxml和wxss)都是单独的Webview来承载,称之为AppView。所以⼀个⼩程序打开⾄少就会有2个webview进程,正式因为每个视图都是⼀个独⽴的webview进程,考虑到性能消耗,⼩程序不允许打开超过5个层级的页⾯,当然同是也是为了体验更好。1、AppService可以理解AppService即⼀个简单的页⾯,主要功能是负责逻辑处理部分的执⾏,底层提供⼀个WAService.js的⽂件来提供各种api接⼝,主要是以下⼏个部分:消息通信封装为WeixinJSBridge(开发环境为window.postMessage,IOS下为WKWebview的window.webkit.messageHandlers.invokeHandler.postMessage,android下⽤WeixinJSCore.invokeHandler)⽇志组件Reporter封装wx对象下⾯的api⽅法全局的App,Page,getApp,getCurrentPages等全局⽅法还有就是对AMD模块规范的实现然后整个页⾯就是加载⼀堆JS⽂件,包括⼩程序配置config,上⾯的WAService.js(调试模式下有asdebug.js),剩下就是我们⾃⼰写的全部的js⽂件,⼀次性都加载。2、线上环境⽽在上线后是应⽤部分会打包为2个⽂件,名称app-config.json和app-service.js,然后微信会打开webview去加载。线上部分应该是微信⾃⾝提供了相应的模板⽂件,在压缩包⾥没有找到。WAService.js(底层⽀持)app-config.json(应⽤配置)app-service.js(应⽤逻辑)然后运⾏在JavaScriptCore引擎⾥⾯。3、AppView这⾥可以理解为h5的页⾯,提供UI渲染,底层提供⼀个WAWebview.js来提供底层的功能,具体如下:消息通信封装为WeixinJSBridge(开发环境为window.postMessage,IOS下为WKWebview的window.webkit.messageHandlers.invokeHandler.postMessage,android下⽤WeixinJSCore.invokeHandler)⽇志组件Reporter封装

wx对象下的api,这⾥的api跟WAService⾥的还不太⼀样,有⼏个跟那边功能差不多,但是⼤部分都是处理UI显⽰相关的⽅法⼩程序组件实现和注册VirtualDOM,Diff和RenderUI实现页⾯事件触发在此基础上,AppView有⼀个html模板⽂件,通过这个模板⽂件加载具体的页⾯,这个模板主要就⼀个⽅法,$gwx,主要是返回指定page的VirtualDOM,⽽在打包的时候,会事先把所有页⾯的WXML转换为ViirtualDOM放到模板⽂件⾥,⽽微信⾃⼰写了2个⼯具wcc(把WXML转换为VirtualDOM)和wcsc(把WXSS转换为⼀个JS字符串的形式通过style标签append到header⾥)。4、Service和View通信使⽤消息publish和subscribe机制实现两个Webview之间的通信,实现⽅式就是统⼀封装⼀个WeixinJSBridge对象,⽽不同的环境封装的接⼝不⼀样,具体实现的技术如下:(1)windows环境通过window.postMessage实现(使⽤chrome扩展的接⼝注⼀⼊个contentScript.js,它封装了postMessage⽅法,实现webview之间的通信,并且也它通过chrome.runtime.connect⽅式,也提供了直接操作chromenative原⽣⽅法的接⼝)发送消息:window.postMessage(data,‘*’);//data⾥指定webviewID接收消息:window.addEventListener(‘message’,messageHandler);//消息处理并分发,同样⽀持调⽤nwjs的原⽣能⼒。(2)IOS通过WKWebview的window.webkit.messageHandlers.NAME.postMessage实现微信navite代码⾥实现了两个handler消息处理器:invokeHandler:调⽤原⽣能⼒publishHandler:消息分发六、性能优化主要的优化策略可以归纳为三点:(1)精简代码,降低WXML结构和JS代码的复杂性;(2)合理使⽤setData调⽤,减少setData次数和数据量;(3)必要时使⽤分包优化。1、setData⼯作原理⼩程序的视图层⽬前使⽤WebView作为渲染载体,⽽逻辑层是由独⽴的JavascriptCore作为运⾏环境。在架构上

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论