this.setData({ a: 1 })
this.setData({ b: 2 })
// 可优化为
this.setData({ a: 1, b: 2 })
// 接口返回数据
let a = {
name: '豆浆',
age: 11,
other: '与渲染无关的字符串'
}
// 修改非实际更新所需数据
let a = {
name: '豆浆',
age: 11
}
// 可优化为
this.setData({ a })
终极目标:类似需求前端只开发一次,后期迭代由后端开发完成后直接上线。
this.setData({
`list[${index}]` = newList[index]
})
自定义组件的更新只在组件内部进行,不会影响页面其他元素。因为各个组件具有独立的逻辑空间、数据、样式环境及 setData 调用。 基于自定义组件的 Shadow DOM 模型设计,我们可以将页面中一些需要高频执行 setData 更新的功能模块(如倒计时、进度条等)封装成自定义组件嵌入到页面中。 当这些自定义组件视图需要更新时,执行的是组件自己的 setData,新旧节点树的对比计算和渲染树的更新都只限于组件内有限的节点数量,有效降低渲染时间开销。
当然,并不是使用自定义组件越多会越好,页面每新增一个自定义组件, Exparser 需要多管理一个组件实例,内存消耗会更大。因此要合理的使用自定义组件,同时页面设计也要注意不滥用标签
常见的控制代码包大小的方法如下:
// 比方平常最常见的this.data的数据
data: {
name: '豆浆',
age: 11,
job: '搬砖工'
}
// 优化前
this.setData({
name: this.data.name,
age: this.data.age,
job: this.data.job
})
// 或者
let name = this.data.name;
let age= this.data.age;
let job= this.data.job;
this.setData({ name, age, job });
// 优化后 利用es6
let { name, age, job } = this.data;
this.setData({ name, age, job });
小程序中可能有n个页面,所有的这些页面,虽然都拥有自己的webview(渲染层), 但是却共享同一个js运行环境。也就是说,当你跳到了另外一个页面(假设是B页面),本页面(假设是A页面)的定时器等js操作仍在进行,并且不会被销毁,并且会抢占B页面的资源。
在h5的环境中,当我们跳转到其他页面,老页面的js环境会被自动销毁,定时器什么都被销毁掉了,因此我们不需要关心老页面中,还有哪些js代码可能还会执行。但是在小程序中,我们必须手动的“清理”掉这样的代码
pageScroll 事件,也是一次通讯,是webview层向js逻辑层的通讯。这次通讯也是开销较大,如果考虑到这个事件被频繁的调用,回调函数如果有复杂的setData的话, 性能就会很差了。
在h5 中的环境中,为了实现懒加载、下拉加载,我们不得不去获取节点的位置。
为啥说不得不,是因为我们本可以用新的api ——intersectionObject去轻松实现(google等主流浏览器都已经支持了),但是微信的内置X5浏览器很遗憾的不支持。
没想到,在小程序的环境中,微信竟然良心发现,支持intersectionObject api, 因此获取节点的信息,尽量还是用这api 吧
可使用事件订阅的方式提前触发事件(比方onfire.js)
onfire.js下载地址: https://www.bootcdn.cn/onfire.js/
onfire.js使用方式: https://www.oschina.net/p/onfire-js
参考文章;
https://blog.csdn.net/sinat_27612147/article/details/80798452
https://developers.weixin.qq.com/community/develop/doc/0008c0b52183d0d9e127da95f5b006
http://www.xcxwo.com/component/view/28dc0cd2a0532b75bdcd092e82d64a7b
目的:提前加载目标页面请求,大幅缩短目标页面白屏时间。
原理:预测用户从页面 A 进入页面 B 的可能性较大,在页面 A 内主动调用页面 B 的预加载处理函数,提前加载请求。进入页面 B 后,使用预加载数据渲染首屏
缺点:
缓存是一种备受青睐的性能优化方法。不仅可以减少请求数,降低弱网场景空窗率,合理利用缓存甚至能使首屏耗时缩短至少 30%以上。
它适用于数据稳定性强,时效性要求低的场景,如图片、字体、配置文件等。
像购物车这种,商品列表变化比较频繁的场景能否使用缓存?
答案是肯定。
scroll-view 组件是一种滚动视图容器,它提供了一个名为 scroll-into-view 的功能,可以使视图滚动到指定元素,为方便描述,下文简称定位功能。
1、背景
购物车很多场景用到定位功能,小程序不支持 DOM 操作,使我们不得不使用 scroll-view 这个大型组件。
但是,scroll-view 组件存在较多性能问题:
2、难点
想要移除 scroll-view,必须找到定位功能的替代方案。在微信基础库版本 2.7.3 以上版本,可使用 wx.pageScrollTo 的定位到锚点功能,对于 2.7.3 以下版本,需要自己编码实现。
示例代码:
_pageScrollTo ({ partten }) {
if (this.createSelectorQuery && wx.pageScrollTo) {
const query = this.createSelectorQuery()
query.selectViewport().scrollOffset()
query.select(partten).fields({ rect: true })
query.exec(function (res) {
if(res) {
const windowHeight = (wx.getSystemInfoSync() || {}).windowHeight || 619const offsetY = windowHeight * 0.35// 目标位置距离窗口上边界的偏移量const _scrollTop = res[0].scrollTop // 滚动条竖直滚动位置const _top = res[1].top // 目标节点上边界坐标const scrollTop = _scrollTop + _top - offsetY
wx.pageScrollTo({ scrollTop, duration: 0 })
}
})
}
}
建议关闭 wx.pageScrollTo 的滚动动画。在一些低端机器上,滚动过程中页面部分区域会白屏,且不会自动恢复。另外,基础库 2.6.4 以下版本,滚动过程中 fixed 元素会闪烁。
3、效果对比
移除 scroll-view 之后,列表滚动过程中几乎不会白屏。下面是 scoll-view 移除前后效果图。
背景
早期,为缩短白屏时间,购物车使用了分屏渲染技术,把数据分为首屏和非首屏两部分,首屏渲染完成后再渲染非首屏数据。
分屏渲染最大问题在于,一旦非首屏数据量过大,渲染耗时会很长,让用户等待很长时间,最糟的情况可能引起页面假死,严重影响用户体验。
随着业务增长,这个问题带来的影响已经越来越明显,因此我们开始考虑改用分页技术
1、技术选型
难点:
业务复杂。短期内无法实现分页请求数据,只能实现纯前端分页
数据量大。每个商品不仅包含主品的各项信息,还可能附加与商品结构类似的赠品、换购商品等
商品列表顺序动态改变。例如修改商品促销,该商品可能由列表第一项变成最后一项,操作完成后还要定位到该商品
技术选型
综合考虑各种业务场景和各项分页技术的特点,最终决定采用自动分页渲染技术。
2、基本思想
3、循环渲染实现方案对比
通过多次实验对比,最终我们选择时间分片模式。
4、示例
Demo: https://developers.weixin.qq.com/s/XJEDb3mP7Kex
原理: 用 raf 代替定时器,每次 setData 完成后,延迟 16.6ms 左右,再渲染下一页
实现思路:每次 setData 时触发 wxs 事件监听器,在 wxs 事件处理函数中调用 raf,raf 回调执行时调用逻辑层函数渲染下一页
流程图如下:
raf demo 流程图
5、效果对比
下面是使用分屏渲染(左图)与自动分页渲染(右图)的效果图。可操作时间缩短 50%+
图片压缩地址: https://tinypng.com/
小程序中图片占据的整体的大部分空间,所以尽可能的较少图片体积要是很重要的
小程序也是js, 所以模块化开发时理所当然可以的,自带ES6自动转换,不管多细小的东西都可以封装城一个模块,增加每一个代码块的复用性,积小成多,慢慢的就减少了很多多余的代码了,像官方自带的api也可以封装比方弹窗提醒
js可以优化,css当然也可以,根据设计图找到所有共同点,将其写在公共CSS中,减少多余的CSS代码,但不可以滥用,因为若放在app.wxss中会全局引用,那么多余的部分就会导致浪费了
有部分场景需要加载高清图,但在列表展示用,可以使用压缩资源,减少cpu占用率,可以后台返回两种链接,一种为高清图访问链接,一种为压缩后的链接
这里提供一下腾讯云的方式
开通数据万象
绑定存储桶
点击数据万象 -> 存储桶管理 -> 图片处理 ->样式管理
Guetzli图片压缩开启
样式管理 -> 添加样式 -> 根据需求设置
点击预览,会进行页面跳转,获取URLhttp://watermark2-1252106211.image.myqcloud.com/preview.png?imageMogr2/thumbnail/500x/interlace/0
将预览后地址栏的地址进行图片名称替换即可,若需更改宽高,以上面例子为例。替换500x中的500即可
参考文章列表
https://mp.weixin.qq.com/s/Iz3FheStNj6B_Al1bjErYg
https://juejin.im/post/5d4d2b9f5188255d84600a12#heading-2
https://mp.weixin.qq.com/s/aAzwYA_RnKSt-y8xDHTtPQ
https://mp.weixin.qq.com/s/1akI1YhK1zGqxPTa50n65A
https://juejin.im/post/5bdbc28e51882516eb55dd1d#heading-1
https://blog.csdn.net/css_666/article/details/82688651