关于vue.js:Vue性能优化技巧

6次阅读

共计 1780 个字符,预计需要花费 5 分钟才能阅读完成。

函数组件

因为组件的生命周期解决在框架层面上非常耗时,所以,倡议平时尽量应用函数型组件。这样,能够防止不必要的性能损失。只有在模板上申明 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();}
正文完
 0