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

How to redraw Button as a circle in XAML

When using XAML layout, sometimes in order to make...

PHP scheduled backup MySQL and mysqldump syntax parameters detailed

First, let's introduce several common operati...

How to upgrade https under Nginx

Purchase Certificate You can purchase it from Ali...

Mysql implements three functions for field splicing

When exporting data to operations, it is inevitab...

CSS3 realizes draggable Rubik's Cube 3D effect

Mainly used knowledge points: •css3 3d transforma...

Use of align-content in flex layout line break space

1. The effect diagram implemented in this article...

MySQL uses aggregate functions to query a single table

Aggregate functions Acts on a set of data and ret...

Solution to the problem "Table mysql.plugin doesn't exist" when deploying MySQL

Today I deployed the free-installation version of...

Specific use of Linux which command

We often want to find a file in Linux, but we don...

Integration practice of Vue+Element background management framework

Table of contents Vue+ElementUI background manage...

In-depth understanding of asynchronous waiting in Javascript

In this article, we’ll explore how async/await is...

Detailed explanation of built-in methods of javascript array

Table of contents 1. Array.at() 2. Array.copyWith...

Jenkins Docker static agent node build process

A static node is fixed on a machine and is starte...

Vue Router loads different components according to background data

Table of contents Requirements encountered in act...

mysql 8.0.18 mgr installation and its switching function

1. System installation package yum -y install mak...