函数组件

因为组件的生命周期解决在框架层面上非常耗时,所以,倡议平时尽量应用函数型组件。这样,能够防止不必要的性能损失。只有在模板上申明functional属性,就能够实现函数式组件了:

<template functional>    <div>        <div v-if="value" class="on"></div>        <section v-else class="off"></section>    </div></template><script>    export default {        props: ['value']    }</script>

局部变量

平时在援用computed数据进行计算的时候,能够多应用局部变量,这样能够防止多次重复计算。

<template>  <div :style="{ opacity: start / 300 }">{{ result }}</div></template><script>export default {  props: ['start'],  computed: {    base () {      return 42    },    result () {      // 赋值给局部变量,避免反复计算      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>

活用v-show,缩小v-if

对于须要频繁切换的视图来说,应用v-show比v-if更加节约性能。因为v-show能够防止dom节点的销毁和重建

活用提早加载(defer)

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

Defer的实现

export default function (count = 10) {  return {    data () {      return {        displayPriority: 0      }    },    mounted () {      this.runDisplayPriority()    },    methods: {      runDisplayPriority () {        const step = () => {          requestAnimationFrame(() => {            this.displayPriority++            if (this.displayPriority < count) {              step()            }          })        }        step()      },      defer (priority) {        return this.displayPriority >= priority      }    }  }}

分批解决(time slicing)

上面这个性能优化的点是前端通用的,能够用requestAnimationFrame分批次执行大数据量的计算,避免一次性执行的数据太大从而阻塞页面渲染。

比方上面这个例子:

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

能够改写为:

fetchItems({ commit }, { items, splitCount }) {    commit('clearItems');    //新建一个队列    const queue = new JobQueue();    splitArray(items, splitCount).forEach(chunk => queue.addJob(done => {        // 分片        requestAnimationFrame(() => {            commit('addItems', chunk);            done()        });    }));        // 期待所有数据处理结束    awiat queue.start();}