Realization of Performance Optimization of element Shuttle Frame

  • 2021-12-01 16:23:09
  • OfStack

Directory background Solutions New problems Advanced

Background

When the shuttle box processes large amount of data, there are too many DOM nodes rendered, which causes the page jamming problem.
Under the premise of not changing the original logic of components as much as possible, optimize them.

Solutions

Lazy Load-InfiniteScroll Component
Copy the original component from packages/transfer (or change the source code and repackage it to maintain the private library)
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>

In data, pageSize: 20 is defined to indicate the number of data per page showData: [] is only used to show the use and replacement of data filteredData that actually needs to be operated in the above code


 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 number of initialized displays is optional, take 20 here.

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 displayed data increases by 20 (any number), and when it exceeds the maximum length of displayed data.

Therefore, the problem of jamming in large data operation is basically solved. Because of the separation of presentation and logic layers, all operation logic of components does not need to be modified, minimizing differences.

New problems

Manually scrolling to the end of the list and then searching still has the problem of jamming.

Advanced

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

We add an ref=scrollContainer for el-checkbox-group to manipulate the scroll bar,

Define the current page number in data curIndex: 1

The method of pageDown is modified


    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 bar to the top, join down 1 Page, for  0  May trigger boundary problems 
      }
    }

To do this, we also need to add a page-up method


InfiniteScroll  Instruction   Only scroll down is provided. We can expand this command or add scroll up monitor by ourselves 
    mounted(){
        this.$refs.scrollContainer.$el.addEventListener('scroll', this.pageUp)
    },
    beforeDestroy(){
        this.$refs.scrollContainer.$el.removeEventListener('scroll', this.pageUp)
    },

Register 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 1 Page,  -1  Prevent boundary problems. 
      }
    },

When data operations, page content changes, scroll bar will also change, to prevent unpredictable page, data changes, reset the scroll bar and the current page number.


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

At the same time, the ES 104EN is executed at corresponding times in the ES 103EN


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

So far, the performance of the shuttle box with large data volume has been greatly improved.


Related articles: