Implementation of element shuttle frame performance optimization

Implementation of element shuttle frame performance optimization

background

When the shuttle box processes large amounts of data, the page may become stuck due to too many DOM nodes being rendered.
Optimize without changing the original logic of the component as much as possible.

Solution

Lazy loading - InfiniteScroll component first copy the original component from packages/transfer (or change the source code and repackage it for maintenance of private library use)
Will

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

Add to

<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>

Define pageSize in data: 20 to indicate the number of data per page showData: [] is only used for display, replace the actual data to be operated in the above code filteredData

 v-for="item in showData">

At the same time, the corresponding processing in 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);
 }

The initial display quantity is 20 at random.

Finally add the method called when scrolling to the bottom

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));
},

When scrolling down, the length of the displayed data increases by 20 (the number is arbitrary), and the maximum length is displayed when it exceeds.

This basically solves the problem of slowdown in operations with large amounts of data. Since the presentation and logic layers are separated, all operation logic of the components does not need to be modified, minimizing the differences.

New Questions

Manually scrolling to the end of the list and then searching will still cause lag.

Advanced

During the scrolling process, the data at the top is still invisible. This data is not displayed and has no impact on the user experience.
So only 20 pieces of data on the current page need to be displayed.

We add a ref=scrollContainer to el-checkbox-group to operate the scroll bar.

Define the current page number curIndex: 1 in data

And modify the pageDown method

    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" //Scroll the bar to the top and connect to the next page. 0 may trigger boundary problems.}
    }

To do this we also need to add a method to turn the page up

The InfiniteScroll command only provides downward scrolling. We can extend this command and add upward scrolling listener mounted(){
        this.$refs.scrollContainer.$el.addEventListener('scroll', this.pageUp)
    },
    beforeDestroy(){
        this.$refs.scrollContainer.$el.removeEventListener('scroll', this.pageUp)
    },

Register the pageUp method

    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 // Scroll to the bottom and connect to the previous page. -1 prevents border problems.
      }
    },

When performing data operations, the page content changes and the scroll bar will also change accordingly. To prevent unpredictable page turning, the scroll bar and the current page number are reset when the data changes.

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

At the same time, execute initScroll at the corresponding time in watch

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

At this point, the performance of the shuttle frame for large amounts of data has been greatly improved.

This is the end of this article about the implementation of element shuttle box performance optimization. For more relevant element shuttle box performance optimization content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue introduces element Transfer shuttle frame on demand
  • Solution to the problem of stuck when clicking Select All in Element's shuttle box with large amount of data

<<:  Box-shadow and drop-shadow to achieve irregular projection example code

>>:  How to view MySQL links and kill abnormal links

Recommend

Detailed explanation of Docker usage under CentOS8

1. Installation of Docker under CentOS8 curl http...

Detailed explanation of CSS3 animation and new features of HTML5

1. CSS3 animation ☺CSS3 animations are much easie...

The connection between JavaScript constructors and prototypes

Table of contents 1. Constructors and prototypes ...

Detailed explanation of how to migrate a MySQL database to another machine

1. First find the Data file on the migration serv...

MySQL starts slow SQL and analyzes the causes

Step 1. Enable MySQL slow query Method 1: Modify ...

JS deep and shallow copy details

Table of contents 1. What does shallow copy mean?...

Instructions for using the meta viewport tag (mobile browsing zoom control)

When OP opens a web page with the current firmwar...

How to install common components (mysql, redis) in Docker

Docker installs mysql docker search mysql Search ...

How to turn off eslint detection in vue (multiple methods)

Table of contents 1. Problem Description 2. Probl...

How to solve the problem that Seata cannot use MySQL 8 version

Possible reasons: The main reason why Seata does ...

Tutorial on installing rabbitmq using yum on centos8

Enter the /etc/yum.repos.d/ folder Create rabbitm...

Detailed explanation of the usage of the alias command under Linux

1. Use of alias The alias command is used to set ...

Detailed explanation of how to enable slow query log in MySQL database

The database enables slow query logs Modify the c...

JavaScript recursion detailed

Table of contents 1. What is recursion? 2. Solve ...