如何优化element穿梭框性能问题,避免渲染节点多卡顿

Admin 2022-07-01 群英技术资讯 736 次浏览

这篇文章给大家分享的是如何优化element穿梭框性能问题,避免渲染节点多卡顿。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。

背景

穿梭框处理大数据量时,由于渲染的 DOM 节点过多,造成页面卡顿的问题。
在尽量不改变组件原有逻辑的前提下,进行优化。

解决思路

懒加载 - InfiniteScroll 组件
先从 packages/transfer 中将原组件拷出(或者改源码重新打包维护私有库使用)

v-infinite-scroll="pageDown"
:infinite-scroll-immediate="false"

添加到

<el-checkbox-group
        v-show="!hasNoMatch && data.length > 0"
        v-model="checked"
        :size="size"
        :class="{ 'is-filterable': filterable }"
        class="el-transfer-panel__list"
        v-infinite-scroll="pageDown"
        :infinite-scroll-immediate="false"
      >
        <el-checkbox
          class="el-transfer-panel__item"
          :label="item[keyProp]"
          :disabled="item[disabledProp]"
          :key="item[keyProp]"
          v-for="item in filteredData">
            <option-content :option="item"></option-content>
        </el-checkbox>
</el-checkbox-group>

在data中定义pageSize: 20 用来表示每页数据个数showData: [] 仅用来展示使用,替换上述代码中实际需要操作的数据 filteredData

 v-for="item in showData">

同时在watch中相应的处理

data (data) {
    const checked = [];
    this.showData = data.slice(0, this.pageSize);

    const filteredDataKeys = this.filteredData.map(
    (item) => item[this.keyProp]
    );
    this.checked.forEach((item) => {
    if (filteredDataKeys.indexOf(item) > -1) {
        checked.push(item);
    }
    });
    this.checkChangeByUser = false;
    this.checked = checked;
},
filteredData (filteredData) {
    this.showData = filteredData.slice(0, this.pageSize);
 }

初始化展示数量随意这里取 20。

最后添加滚动到底部时调用的方法

pageDown () {
    const l = this.showData.length;
    const totalLength = this.filteredData.length
    l < totalLength && 
    (this.showData = this.filteredData.slice(0, l + this.pageSize > totalLength ?
    totalLength : l + this.pageSize));
},

往下滚动的时候 展示的数据长度增加 20(数量随意), 超出时展示最大长度。

由此基本解决大数据量操作卡顿的问题。由于展示和逻辑层分开,组件的所有操作逻辑无须修改,最小程度减少差异。

新问题

手动滚动到列表末端,再进行搜索操作依然存在卡顿问题。

进阶

在滚动过程中,实际上顶端的数据依旧无法看见,该数据不展示,对用户体验也没有影响,
所以只需展示当前页的 20 条数据。

我们为el-checkbox-group添加一个 ref=scrollContainer 以便操作滚动条,

在data中定义当前页数 curIndex: 1

并对 pageDown 方法进行修改

    pageDown () {
      const totalLength = this.filteredData.length
      if((this.curIndex*this.pageSize) < totalLength){
        this.curIndex ++
        const targetLength = this.curIndex * this.pageSize 
        const endPoint = targetLength > totalLength ? totalLength : targetLength
        const startPoint = endPoint - this.pageSize  > 0 ? endPoint - this.pageSize : 0
        this.showData = this.filteredData.slice(startPoint, endPoint);
        this.$refs.scrollContainer.$el.scrollTop = "1px" //滚动条到最上端,衔接下一页,为 0 可能会触发边界问题
      }
    }

为此我们还需要添加向上翻页的方法

InfiniteScroll 指令 只提供向下滚动,我们可以拓展该指令亦可自行添加上滑滚动监听
    mounted(){
        this.$refs.scrollContainer.$el.addEventListener('scroll', this.pageUp)
    },
    beforeDestroy(){
        this.$refs.scrollContainer.$el.removeEventListener('scroll', this.pageUp)
    },

注册pageUp 方法

    pageUp(e){
      if(e.target.scrollTop ===0 && this.curIndex>1){
        this.curIndex --
        const endPoint = this.curIndex * this.pageSize 
        const startPoint = (this.curIndex-1)* this.pageSize 
        this.showData = this.filteredData.slice(startPoint, endPoint);
        const el = this.$refs.scrollContainer.$el
        el.scrollTop = el.scrollHeight - el.clientHeight - 1 // 滚动到最底部,衔接上一页, -1 防止边界问题。
      }
    },

当进行数据操作的时候,页面内容变化,滚动条也会随之变化,为防止不能预知的翻页,数据改变时,重置滚动条和当前页码。

    initScroll(){
        this.curIndex = 1
        this.$refs.scrollContainer.$el.scrollTop = 0
    },

同时地,在watch中相应时候执行 initScroll

    data(){
        ...
        this.initScroll()
        ...
    },
    filteredData (filteredData) {
      ...
      this.initScroll()
    }

至此大数据量的穿梭框,性能大为改善。


现在大家对于如何优化element穿梭框性能问题,避免渲染节点多卡顿的内容应该都有一定的认识了吧,希望这篇能对大家有所帮助。最后,想要了解更多,欢迎关注群英网络,群英网络将为大家推送更多相关的文章。 群英智防CDN,智能加速解决方案

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

猜你喜欢

成为群英会员,开启智能安全云计算之旅

立即注册
专业资深工程师驻守
7X24小时快速响应
一站式无忧技术支持
免费备案服务
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
在线客服
微信公众号
返回顶部
返回顶部 返回顶部
在线客服
在线客服