小程序的工作原理简单分析

前言

搞前端开发的如果只停留在使用者的层面,那就太low了。大前端的世界丰富多彩。涉及native开发的有facebook的react nativereact系的),阿里的weexvue.js系的)后脚跟进,当然还有以基于phonegapionic为首的hybrid开发大行其道。涉及PC桌面端跨平台的有electronnwjs。而这里说到的小程序主要是指微信小程序(以微信小程序为例,其他百度小程序、支付宝小程序、今日头条小程序等都与微信小程序神似……)

当我们打开小程序发生了什么?

Duang, Duang, Duang那三个点在转啊转,大家应该都猜到,一定是拼命在加载此什么东西了。原来此时微信正在加载小程序的完整包。其命名的格式一般是数字命名的如:_-2082693788_4.wxapkg

根据官方描术,这个包文件里面就包含了逻辑层的js视图层的wxml、wxss还有一些小程序的配置json文件。如下图:

那么这堆东西加载完之后,如何渲染页面呢?好吧,先简单了解一下一些先驱们正在做的事情。

如react native,让大家可以使用前端的技术react来进行native开发。怎么玩?react native构建时,会把你的项目文件react写的前端页面全部打包成一个jsbundle即js包、一个android项目及一个ios项目;之后你可以把这个js包上传到项目中已经配置好的cdn地址服务器上,把android项目打包出apk文件,把ios项目打包出安装包(可以是用苹果开发者帐号打包上传到appstore或者非开发者帐号时打包上传到蒲公英等企业测试包)。weex与rn类似,也把jsbundle打包出来上传到cdn服务器,也分别生成了一个android项目及一个ios项目。因为APP里面已自带的javascript引擎可以对js进行解释及处理,并生成相应的UI交互界面。这里主要是javascript引擎与原生界面的互动。用户安装了相应单独打包出来的APP后,打开APP运行时都是先去跟服务器校验一下jsbundle包的版本,如果版本变化了,就会自动去cdn地址下载更新最新的jsbundle包来完成APP的热更新

那么,小程序是怎么玩的呢?我们先看看小程序官方文档是怎么介绍的。

小程序的运行环境

运行环境 逻辑层(jscore) 渲染层(webview)
iOS JavaScriptCore WKWebView
安卓 X5 JSCore X5浏览器
小程序开发者工具 NWJS Chrome WebView

很明显,逻辑层的js代码也是向前辈们学习,运行在javascript引擎里面,然后小程序创新的地方是它用了双线程处理,另外一个线程专门用来处理渲染层的webview。没错,视图层的代码都运行了在实实在在的webview里面。但因为所有的逻辑处理都是由运行在javascript引擎里面的逻辑层代码控制,所以不能处理原生浏览器的dom及bom。

实现猜想:这是一个MVVM框架,而这个过程都是由逻辑层发送数据变更到视图层,然后视图层因为存在一个内置的类Vue的框架js库,通过virtualDom及diff算法来控制渲染层来控制各种交互处理及界面变化及优化渲染。

逻辑层与视图层之间是通过jsBridge进行数据交互的,有做过APP的混合开发的人一定知道hybrid开发时需要用到jsbridge/WebViewJavascriptBridge来处理webview中的h5页面与app之间的数据传递,而这原理其实主要是url传值,动态创建隐藏的iframe并通过src传url值。

而小程序就是用到了这些技术,双线程运行。当你打开了小程序相当于,打开了一个javascript引擎用于处理逻辑层js代码打开了一个或者多个webview进行相应的页面的处理,这就限制了路由的层及不能超过5层,这样会导致同时打开了5个webview影响小程序的性能。还有整个包打包文件不能超过1M,影响小程序的加载速度。

小程序的开发者工具

由上面的小程序的运行环境的表可以看到,小程序的开发工具是用NWJS开发的。这应该是与腾讯团队的强大的C++背景有很大的关系,因此在nwjs及electron之间选择了对C++控制js更加方便的nwjs来进行使用前端技术开发跨平台的桌面端的应用。

NWJS,它本身也是基于WEB技术体系实现的,据说开发工具是nwjs+react,nwjs是什么:简单是说就是node+webkit,node提供给我们本地api能力,而webkit提供给我们web能力,两者结合就能让我们使用JS+HTML实现本地应用程序。既然有nodejs,那上面的打包选项里的功能就好实现了。

作者: 博主

Talk is cheap, show me the code!

发表评论

电子邮件地址不会被公开。

Captcha Code