从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现 (2)

从dom变化可以看出,调用navigateTo相当于新打开一个webview加载另一个页面视图,随着打开的页面越来越多,内存就比较吃紧。这也是为什么小程序对打开页面数量有限制的原因。从图中可能也看出了,为啥多加载了一个pageframe.html的webview,这个是干什么用的?后面会说到它的作用。

视图层页面的实现

我们在写小程序页面视图时,貌似并不关心webview中的html结构,这些都是小程序底层帮我们实现, 我们只需要写页面ui和业务逻辑即可。下面我们来看看view视图层小程序帮我们做了什么。先来看一下视图层pageframe.html的模板:

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现


其中,模板中的注释占位符经过后台服务处理会注入不同js脚本,主要js内容:

<!-- deviceinfo -->: 暂时无用的占位符,会被空字符串""替换

<!-- jsdebug -->: 提供视图层的WeixinJSBridge模拟实现以及一些事件的处理如enablePullDownRefresh,其对应的js内容为extensions/pageframe/index.js.

<!-- plugincode -->: 小程序插件相关的代码,若小程序使用插件则会注入

<!-- wxmlcode -->: 调用wcc可执行命令生成的小程序注册所有页面wxml对应的js脚本内容

<!-- wxsscode -->: 调用wcss可执行命令生成的js脚本内容,提供注入css到页面的js方法;该内容会提前注入全局的css。

<!-- wxappcode -->: 小程序当前视图页面相关的配置json内容以及wxml和wxss转换为js的内容,可在控制台输入__wxAppCode__看相关信息

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

<!-- vendorlist -->: 小程序为视图层注入的基础库功能,包括WAWebview.js、WARemoteDebug.js和hls.js

视图层页面实现技术细节

本节来详细介绍下小程序视图层实现的一些技术细节

视图层快速打开原理

首先看一下小程序官网页面层级准备小节描述的一段内容:

wx.navigateTo会创建一个新的页面层级,对于每一个新的页面层级,视图层都需要进行一些额外的准备工作。在小程序启动前,微信会提前准备好一个页面层级用于展示小程序的首页。除此以外,每当一个页面层级被用于渲染页面,微信都会提前开始准备一个新的页面层级,使得每次调用wx.navigateTo都能够尽快展示一个新的页面。

正如上文提到的,我们在打开pages/logs/logs视图页面时,发现dom中多加载了一个__pageframe__/pageframe.html的视图层,其模板内容正如上一节描述的。这个视图层的作用正是为了小程序提前为一个新的页面层准备的。

小程序每个视图层页面内容都是通过pageframe.html模板来生成的,包括小程序启动的首页;下面来看看小程序为快速打开小程序页面做的技术优化:

首页启动时,即第一次通过pageframe.html生成内容后,后台服务会缓存pageframe.html模板首次生成的html内容

非首次新打开页面时,页面请求的pageframe.html内容直接走后台缓存

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

非首次新打开页面时,pageframe.html页面引入的外链js资源(如上图所示)走本地缓存

这样在后续新打开页面时,都会走缓存的pageframe的内容,避免重复生成,快速打开一个新页面。

视图层新打开页面流程

其实在小程序开发者工具实现中,在创建每个视图层页的webview时,都会为其绑定了onLoadCommit事件(它会在页面加载完成后触发,包含当前文档的导航和副框架的文档加载)。初始时webview的src会被指定为空页面地址:${global.proxyPort}/aboutblank?${c},其中c为对应webview的id。webview从空页面到具体页面视图的过程如下:

空页面地址webview加载完毕后执行事件中的reload方法,即设置webview的src为pageframe地址:${global.proxyPort}/__pageframe__/pageframe.html。

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

加载完成后,设置其src为pageframe.html:

从微信小程序开发者工具源码看实现原理(二)- - 小程序技术实现

新的src内容加载完成后再次触发onLoadCommit事件但根据条件不会执行reload方法。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfzzp.html