27分8次助攻 球队失利难掩方硕光芒
# 1. 适当监听页面或组件的 scroll 事件
百度 《中华人民共和国治安管理处罚法》第二十六条有下列行为之一的,处五日以上十日以下拘留,可以并处五百元以下罚款;情节较重的,处十日以上十五日以下拘留,可以并处一千元以下罚款:(一)结伙斗殴的;(二)追逐、拦截他人的;(三)强拿硬要或者任意损毁、占用公私财物的;(四)其他寻衅滋事行为。只要用户在 Page 构造时传入了 onPageScroll 监听,基础库就会认为开发者需要监听页面 scoll 事件。此时,当用户滑动页面时,事件会以很高的频率从视图层发送到逻辑层,存在一定的通信开销。
类似的,对于 <scroll-view>
、<page-meta>
等可以通过 bindscroll 监听滑动事件的组件,也会存在这一情况。
正是由于 scroll 事件触发的频率很高,因此开发者很容易误用,在使用时需要注意:
- ? 非必要不监听 scroll 事件;
- ? 在实现与滚动相关的动画时,优先考虑滚动驱动动画(仅
<scroll-view>
)或 WXS 响应事件 - ? 不需要监听事件时,Page 构造时应不传入 onPageScroll 函数,而不是留空函数;
- ? 避免在 scroll 事件监听函数中执行复杂逻辑;
- ? 避免在 scroll 事件监听中频繁调用 setData 或同步 API。
Page({
onPageScroll () {} // ?不要保留空函数
})
Page({
// ? 应直接不传入
})
# 2. 选择高性能的动画实现方式
开发者在开发界面动画时,应该选择高性能的动画实现方式。
- ? 优先使用 CSS 渐变、CSS 动画、或小程序框架提供的其他动画实现方式完成动画;
- ? 在一些复杂场景下,如果上述方式不能满足,可以使用 WXS 响应事件 动态调整节点的 style 属性做到动画效果。同时,这种方式也可以根据用户的触摸事件来动态地生成动画;
- ? 避免通过连续 setData 改变界面的形式来实现动画。虽然实现起来简单灵活,但是极易出现较大的延迟或卡顿,甚至导致小程序僵死;
- ? 如果不得不采用 setData 方式,应尽可能将页面的 setData 改为自定义组件中的 setData 来提升性能。
# 3. 使用 IntersectionObserver 监听元素曝光
部分业务场景会需要监控元素曝光情况,用于进行一些页面状态的变更或上报分析。
- ? 建议使用节点布局相交状态监听 IntersectionObserver 推断某些节点是否可见、有多大比例可见;
- ? 避免通过监听 onPageScroll 事件,并在回调中通过持续查询节点信息 SelectQuery 来判断元素是否可见。
# 4. 控制 WXML 节点数量和层级
一个太大的 WXML 节点树会增加内存的使用,样式重排时间也会更长,影响体验。
- ? 建议一个页面 WXML 节点数量应少于 1000 个,节点树深度少于 30 层,子节点数不大于 60 个。
# 5. 控制在 Page 构造时传入的自定义数据量
为了便于开发,开发者可以添加任意的函数或数据到 Page 构造传入的 Object 参数中,并在页面的函数内用 this 访问。例如:
Page({
data: {}
userInfo: {} // 自定义数据
currentUser: 'Wechat' // 自定义数据
onTap() { }
onLoad() {
console.log(this.currentUser)
}
})
为了保证自定义数据在不同的页面实例中也是不同的实例,小程序框架会在页面创建时对这部分数据(函数类型字段除外)做一次深拷贝,如果自定义数据过多或过于复杂,可能带来很大的开销。
- ? 对于比较复杂的数据对象,建议在
Page onLoad
或Component created
时手动赋值到 this 上,而不是通过 Page 构造时的参数传入。
// ? 使用复杂对象作为自定义数据
Page({
onLoad() { }
bigData: { /* A complex object */ },
longList: [ /* A long complex array*/ ]
})
// ? 运行时手动赋值到 this。开发者可以根据需要选择进行深拷贝、浅拷贝或不拷贝。
Page({
onLoad() {
this.bigData = { /* A complex object */ },
this.longList = [ /* A long complex array*/ ]
}
})