前言:
我们在做移动端的点餐程序的时候,发现当菜品数量巨大的时候,特别是外加很多操作的时候(比如菜品半整份切换的时候)
,列表里面的菜品数量 进行快速 加减和半整份切换就会卡顿。
那到底是什么让手机如此卡顿呢?
我写了个用例,用了2277条数据(找不到性能差的手机,可以适当增加数据量来测试)
在 红米3(
安卓版本:5.1.1 LMY47V)
上做了个实验。
Normal.vue为普通暴力渲染模式,Optimize.vue优化后的模式;
demo 地址:github.com/trsoliu/vue…
1.发生的原因:
当我们拿一个数组list用v-for直接把数组里的对象渲染到页面上的时候,其实,已经为后续的性能埋下了雷。
Normal.vue
<template>
<div class="normal">
普通列表
<ul>
<li v-for="(item,index) in list">
<img :src="item.img" />
<div class="left_bottom" >
<p>{{item.name}}</p>
<p><span v-if="item.num > 0">{{item.num}}整份</span><span v-if="item.num > 0">{{item.num}}半份</span></p>
<span class="add btn" @click="add(index)">+</span>
<span class="num">{{item.num}}</span>
<span class="reduce btn" @click="reduce(index)">-</span>
</div>
</li>
</ul>
</div>
</template>
<script> import list from "./list.js" export default { name: 'normal', data() { return { list: list } }, methods: { add(index) { let t = this; console.log(index, "+"); t.list[index].num++; }, reduce(index) { let t = this; t.list[index].num > 0 ? t.list[index].num-- : 0; } } } </script>
在这里,每次触发➕或者➖来操作菜品数据时,都需要操作原list数组。
每次操作完原数组后,原数组list发生变化,会重新走一遍v-for进行页面重绘渲染(即使官方有跟踪每个节点的标识key,做重用和重新排序现有元素)
,那其实这个过程在少量数据的时候没什么影响,vue的速度很快。
但当用户的手机是那种300-1000块的街机或者系统老旧的时候,这里的性能问题就尤为的明显了;你会发现快速操作菜品加减的时候,菜品数字变化会缓慢或者直接跳值(比如直接从2变成5)
,同时你滑动页面的时候页面滚动也是卡顿的,因为这个时候页面在渲染,滚动条也会短时间停滞;
海量数据下,这种用户体验十分的糟糕,并且为我发现市场大部分的列表操作都有这类的问题。
2.解决办法
写一个单独的组件,将数组list中的每一个对象传给子组件(Operate.vue)
,组件用props接受到后,之后只操作传过来的这个对象,不改变原数组list中的任何值;
备注:这里为将一个数组变为两个,一个为 listOriginal 仅做初次渲染使用,另外一个listOperate 在组件回调后操作,用来做渲染之外的业务处理。这样页面渲染和业务操作通过子组件达到互补干扰的效果,页面也会极其流畅了。
以下红框为单独组件渲染结果:
父组件:Optimize.vue
<template>
<div class="optimize">
优化列表
<ul>
<Operate v-for="(item,index) in listOriginal" :item="item" :index="index" :key="index"></Operate>
</ul>
</div>
</template>
<script> import list from "./list.js" export default { name: 'optimize', data() { return { listOriginal: JSON.parse(JSON.stringify(list)),//仅做初次渲染使用 listOperate:JSON.parse(JSON.stringify(list))//组件回调后操作,用来做渲染之外的业务处理 } }, components:{ Operate: function(resolve) { require(['@/components/Operate.vue'], resolve) } } } </script>
子组件:Operate.vue
<template>
<li class="operate">
<img :src="item.img" />
<div class="left_bottom">
<p>{{item.name}}</p>
<p><span v-if="item.num > 0">{{item.num}}整份</span><span v-if="item.num > 0">{{item.num}}半份</span></p>
<span class="add btn" @click="add(index)">+</span>
<span class="num">{{item.num}}</span>
<span class="reduce btn" @click="reduce(index)">-</span>
</div>
</li>
</template>
<script> export default { name: 'operate', data() { return {} }, props: ["item", "index"], methods: { add(index) { let t = this; t.item.num++; //t.$emit(...);//回调操作父组件listOperate,或者处理其他业务均可 }, reduce(index) { let t = this; t.item.num > 0 ? t.item.num-- : 0; //t.$emit(...);//回调操作父组件listOperate,或者处理其他业务均可 } } } </script>
通过改变数据的使用方式,和合理利用框架,达到性能的优化。
以上大概就是我写的用例的基本对比情况,如果疑问可以留言给我或者加群,我都会一一解答的。
有问题可以加群交流535798405;
demo 地址:github.com/trsoliu/vue…
今天的文章vue海量数据列表操作的性能优化,渣渣手机性能一秒变丝滑!分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21504.html