关于小程序在初次加载时遇到的包问题,小程序已推出了一种名为分包加载的解决方案,具体内容此处不予详述,感兴趣者可查阅官方发布的文档资料。
这里我选择的是针对渲染节点去做优化。
技术方案
在微信的api文档里面,有一个判断节点与可视区域的API
该对象旨在判断特定节点是否在用户视野范围内、以及其可见部分的占比大小。
此刻心中所思,便是能否构建一种关联,让组件在踏入可视范围时自动展示其内容,若不在可视区域内则予以隐藏,进而实现模块的动态加载效果。
// 伪代码 // 建立监听 element.observer() // 处理进入 observer.handleEnterView(() => { callback() // 处理回调 disconnect() // 销毁 }) 复制代码
<view class="component"> <"component-header">view> <"component-observer" wx:if="{{ observer_status}}">"component-content" wx:else> view> view> 复制代码
开发阶段
建立了基本技术方案之后,就开始到代码层面了
Component({ data: { observer_status: true },// 在ready写是因为组件在这个时候,才在视图层布局完成 ready () { 鉴于我们将设备的整体可视范围设定为参照区域,因此在此处直接选取了relativ。etoViewport,如果需要其他的观察区域可以调用relativeto选择参照区域 this.observer = this创建一个IntersectionObserver实例,并对其执行相关操作。etoViewport() // 我这里的做法是,只要观察的节点进入了可视区域,就显示自己本身的内容 实际上,该观察者的回调函数是在节点进入或退出可见区域时被触发的,而在我这里,我所采用的是,无论何时执行都会引发。显示这个区域,并且关闭这个观察 this.observer.observe('.observer',(res) => { this.setData({
优化
你们以为这就完了么,并没有。
它由或构成。在针对该对象进行定义时,需在Page中进行操作。若观察的对象数量较多,则需设定参数:all。然而,官方文档中提到,若同时选择过多节点,可能会对渲染性能产生不利影响。
就组件开发而言,若每个组件均如此编写,其是否会如同`:all`那般对渲染性能造成影响尚不明确;若确实存在影响,或许只能通过减少观察对象或构建一个大容器来进行观察。然而,若每个组件都采取这种方式编写,过程将变得异常繁琐。
此刻,组件的优势显现出来。在创建组件的过程中,存在一个极具魔力的特性,那就是……简而言之,它本质上是一种代码复用机制。通过直接运用……,组件便能够自动获取若干方法和属性。借助这一特性,我们可以在组件内部减少大量的代码编写。
,detached () { this.observer.disconnect() } }) 复制代码
) Component({ behaviors: [mixin] }) 复制代码
代码
或者你可以把整个做成组件,这样去减少的数量,内聚一些模块
需要注意的是对于组件来说,如果observer的话就需要一个留意该节点,同时确保其为一个高度非零且可被视见的实体,若希望该节点具备高度同时又不希望它对其他方面造成干扰,页面位置的话可以用一些hack的方法
.component-observer { height: 1rpx; margin-top: -1rpx; } 复制代码
后续一些讨论
在应用该功能时,我曾尝试利用某些属性。然而,即便如此,那些属性同样会被页面所呈现,尽管它们并未在界面上显现,但这并不会对页面的加载速度产生任何积极影响。
效果图
这里是随便拿的一个demo去弄的,需要的话可以点击 这里
或者浏览小程序代码片段
使用之前
使用之后
如果图片不动的话可以点击查看 可以看得出是提升是相当明显的
后续进阶图片方案
存在一个名为lazy-load的特性,但此特性仅限于在page和-view中应用。那么,在其他场景下,我们是否也可以利用这一特性呢?
代码
对相关数据进行,以编号51为基准,实施严格的限制。: { _src: "default_image" },ready () { // 伪代码 observer('.observer-picture') .then(() => { this.setData({ _src: this.properties.imageSrc }) }) } }) 复制代码