Vue performance optimization method

The examples are from https://www.youtube.com/watch?v=5B66qer8cZo Partially reproduced in link: https://www.jianshu.com/p/f372d0e3de80

Functional components

Because the life cycle processing of components is very time-consuming at the framework level, it is recommended to use functional components as much as possible. In this way, unnecessary performance loss can be avoided. As long as the functional attribute is declared on the template, the functional component can be implemented:

<template functional>
    <div>
        <div v-if="value" class="on"></div>
        <section v-else class="off"></section>
    </div>
</template>

<script>
    export default {
        props: ['value']
    }
</script>

Sub component split

Another optimization technique is to put complex and time-consuming computing processing into subcomponents:

<template>
    <div :style="{opacity: number / 300 }">
        <ChildComp />
    </div>
</template>

<script>
    export default {
        props: ['number'],
        components: {
            ChilComp: {
                methods: {
                    heavy() {
                        // heavy task
                    }
                },
                render(h) {
                    return h('div', this.heavy())
                }
            }
        }
    }
</script>

local variable

Usually, when using calculated data for calculation, you can use more local variables, which can avoid repeated calculation.

<template>
  <div :style="{ opacity: start / 300 }">{{ result }}</div>
</template>

<script>
export default {
  props: ['start'],
  computed: {
    base () {
      return 42
    },
    result () {
      // Assign to local variable to prevent repeated calculation
      const base = this.base;
      let result = start
      for (let i = 0; i < 1000; i++) {
        result += Math.sqrt(Math.cos(Math.sin(base))) + base * base + base + base * 2 + base * 3
      }
      return result
    },
  },
}
</script>

Using v-show to reduce v-if

For views that need to switch frequently, using v-show is more economical than v-if. Because v-show can avoid the destruction and reconstruction of dom nodes, we can use the following example

<template functional>
    <div class="cell">
        <div v-if="props.value" class="on">
            <Heavy :n="10000" />
        </div>
        <section v-else class="off">
            <Heavy :n="10000" />
        </section>
    </div>
</template>


//Rewrite as

<template functional>
    <div class="cell">
        <div v-show="props.value" class="on">
            <Heavy :n="10000" />
        </div>
        <section v-show="!props.value" class="off">
            <Heavy :n="10000" />
        </section>
    </div>
</template>

Use keep alive

Another common optimization technique is to use keep alive, which is usually used in the routing switching component:

<template>
    <div id="app">
        <keep-alive>
            <router-view />
        </keep-alive>
    </div>
</template>

Defer load

<template>
  <div class="deferred-off">
    <VueIcon icon="fitness_center" class="gigantic"/>

    <h2>I'm an heavy page</h2>

    <Heavy v-for="n in 8" :key="n"/>

    <Heavy class="super-heavy" :n="9999999"/>
  </div>
</template>
<template>
  <div class="deferred-on">
    <VueIcon icon="fitness_center" class="gigantic"/>

    <h2>I'm an heavy page</h2>

    <template v-if="defer(2)">
      <Heavy v-for="n in 8" :key="n"/>
    </template>

    <Heavy v-if="defer(3)" class="super-heavy" :n="9999999"/>
  </div>
</template>

<script>
import Defer from '@/mixins/Defer'
export default {
  mixins: [
    Defer(),
  ],
}
</script>

Time slicing

The following performance optimization points are common to the front-end. You can use the requestAnimationFrame to perform large amount of data calculation in batches to prevent one-time execution of too large data to block page rendering.

For example:

fetchItems({ commit }, { items }) {
    commit('clearItems');
    commit('addItems', items)
}


//It can be rewritten as:

fetchItems({ commit }, { items, splitCount }) {
    commit('clearItems');
    //Create a new queue
    const queue = new JobQueue();
    splitArray(items, splitCount).forEach(chunk => queue.addJob(done => {
        // Fragmentation
        requestAnimationFrame(() => {
            commit('addItems', chunk);
            done()
        });
    }));
    
    // Wait for all data processing to complete
    awiat queue.start();
}

Non reactive mode

For complex data structures, we can explicitly declare them as nonresponsive, which can avoid many unnecessary calculations and improve performance

const data = items.map(item => optimizeItem(item));

function optimizeItem (item) {
    const itemData = {
        id: uid ++,
        vote: 0
    };
    Object.defineProperty(itemData, 'data', {
        // mark as non-reactive
        configurable: false,
        value: item
    });
    return itemData
}

Rendering visualization only

For an infinite list, the main method of performance optimization is to keep rendering only the visual part.

Here's an example:

<div class="items no-v">
    <FetchItemViewFunctional v-for="item of items" :key="item.id" :item="item" @vote="voteItem(item)">
    </FetchItemViewFunctional>
</div>

This is the most common way to write, but if there is a lot of content in the list, you will find that the page is very stuck. At this time, you can use vue-virtual-scroller This component is optimized:

<recycle-scroller
    class="item"
    :items="items"
    :item-size="24"              
>
    <template v-slot="{item}">
        <FetchItemView :item="item" @vote="voteItem(item)"/>
    </template>
</recycle-scroller>

In this way, the fluency and performance of components can be greatly improved.
 

 

Keywords: Attribute Vue

Added by coditoergosum on Mon, 22 Jun 2020 10:53:47 +0300