背景
wepy 1.7.3
wepy-redux
长列表交互问题
wepy 框架的列表性性能比较差,主要原因是修改列表中任意字段的时候,会给 setData 传递完整的列表,详细见这个 issue;
此时修改长列表任意字段,都会导致页面长时间不响应
解决
使用字典 (Object) 与长列表进行组合,因为一般情况下字典的数据量会远远小于列表
场景
任意弹窗对购物车 cart 进行修改,产品列表对应的购买数量同步修改
// 数据结构
// 产品列表(长度 3000+)
var products = [{id: “79”, name: “ 精致荤菜 ”}…]
// 购物车字典
// key: productId, value: 购物车数据
var cartDict = {
2407: {
price: “1.02”
num: 2
}
}
注意由于 cartDict 数据为用户手动添加,数据量远远小于列表。那么 setData 时速度也会相应提高
此时我们使用组合方式渲染列表的购买量
<view class=”num” wx:if=”{{cartDict[product.id] }}”>{{cartDict[product.id].num}}</view>
通过将每次修改列表转移为每次修改 cartDict 来达到提升性能的效果;上面那个 issue 也可以用类似思路制作一个展开产品的字典
首次加载白屏问题
我们的商品列表一般会比较长(目前最大有 3000+ 个),此时第一次进入页面白屏时间很长(10s+);
解决
使用 h5 的优化思路,类似 app。只渲染一部分屏幕内的产品,其他绝大部分产品使用骨架展示;使用此方法有一些限制
产品高度需要已知,用来计算当前产品是否在屏幕内
滚动体验没有不优化的好,小程序其实也是用的这种列表优化思路,因此快速滚动的时候实际效果是
白屏(小程序优化) => 骨架(我们的优化) => 出现产品
场景
我们项目所有产品等高,因此比较好计算当前产品是否应该展示。
首先是模板写法
<repeat for=”{{products}}” item=”dish” index=”index”>
<dishItem :dish=”dish”
wx:if=”{{showTypeDict[type.id]}}”></dishItem>
<view wx:else>
<image src=”{{_skeleton}}”></image>
</view>
</repeat>
说明:
showTypeDict 代表当前需要展示的产品字典,使用字典原因是基于长列表交互问题
对产品进行分类,每次只比较分类的坐标然后展示整个分类
dishItem 是产品对应组件,比较复杂
skeleton 为骨架
监听 scroll,根据当前 scrollTop 和产品分类的坐标来决定 showTypeDict 的内容,注意截流;
使用以上方法优化后 3000+ 产品白屏时间与 100+ 产品持平。滚动时无卡顿,快速滚动时需要等待一会儿产品才能渲染出来;
以上