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