17.vue性能优化9法。

1.函数型组件优化:使用函数型组件。只要在模板上声明functional属性,就可以实现函数式组件。

  • 1-1.优化前:
<template>
  <div class="cell">
    <div v-if="value" class="on"></div>
    <section v-else class="off"></section>
  </div>
</template>
<script>
export default {
  props: ['value']
}
</script>

在这里插入图片描述

  • 1-2.优化后:有组件生命周期的有很多耗时处理,而作为函数式组件处理提升页面效率。
    • ①组件的生命周期处理在框架层面上十分耗时,建议平常尽量使用函数型组件。可以避免不必要的性能损失。只要在模板上声明functional属性,就可以实现函数式组件。
    • ②函数式组件特点:
      • α:没有管理任何状态。
      • β:没有监听任何传递给它的状态。
      • γ:没有生命周期方法。
      • ζ:只是接收一些prop的函数。
    • ③适用简单的展示组件。高阶组件用于接收一个组件作为参数,返回一个被包装过的组件。v-for循环中每项通常都是很好的用做函数式组件的候选项。
<template functional>
  <div class="cell">
    <div v-if="props.value" class="on"></div>
    <section v-else class="off"></section>
  </div>
</template>
<script>
export default {
  props: ['value']
}
</script>

在这里插入图片描述

2.子组件拆分:子组件拆分,将重的函数放在子组件中,因为父子组件生命周期更新的问题。

  • 2-1.优化前:
<template>
  <div :style="{ opacity: number / 300 }">
    <div>{{ heavy() }}</div>
  </div>
</template>
<script>
export default {
  props: ['number'],
  methods: {
    heavy () { /* HEAVY TASK */ }
  }
}
</script>

在这里插入图片描述

  • 2-2.优化后:将重的函数放在子组件中,因为父子组件生命周期更新的问题。
<template>
  <div :style="{ opacity: number / 300 }">
    <ChildComp/>
  </div>
</template>
<script>
export default {
  props: ['number'],
  components: {
    ChildComp: {
      methods: {
        heavy () { /* HEAVY TASK */ }
      },
      render (h) {
        return h('div', this.heavy())
      }
    }
  }
}
</script>

在这里插入图片描述

3.局部变量:.局部变量,将计算属性赋值给局部变量,防止重复计算。

  • 3-1.优化前:
<template>
  <div :style="{ opacity: start / 300 }">{{ result }}</div>
</template>
<script>
import { heavy } from '@/utils'
export default {
  props: ['start'],
  computed: {
    base () { return 42 },
    result () {
      let result = this.start
      for (let i = 0; i < 1000; i++) {
        result += heavy(this.base)
      }
      return result
    }
  }
}
</script>

在这里插入图片描述

  • 3-2.优化后:使用计算属性的时候,把计算属性赋值给一个局部变量,防止重复计算,提高效率。
<template>
  <div :style="{ opacity: start / 300 }">
    {{ result }}</div>
</template>
<script>
import { heavy } from '@/utils'
export default {
  props: ['start'],
  computed: {
    base () { return 42 },
    result () {
      const base = this.base
      let result = this.start
      for (let i = 0; i < 1000; i++) {
        result += heavy(base)
      }
      return result
    }
  }
}
</script>

在这里插入图片描述

4.活用 v-show 减少v-if:

  • 4-1.优化前:
<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>

在这里插入图片描述

  • 4-2.优化后:v-if,是真正的销毁渲染,比较耗性能,v-show不会操作DOM树,性能高。
<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>

在这里插入图片描述

5.Keep-alive:缓存不活跃的组件。

  • 5-1.优化前:
<template>
  <div id="app">
    <router-view/>
  </div>
</template>

在这里插入图片描述

  • 5-2.优化后:缓存不活跃的组件。
<template>
  <div id="app">
    <keep-alive>
      <router-view/>
    </keep-alive>
  </div>
</template>

在这里插入图片描述

6.活用延迟功能:

  • 6-1.优化前:
<template>
  <div>
    <h2>I'm an heavy page</h2>
    <Heavy v-for="n in 10" :key="n"/>
    <Heavy class="super-heavy" :n="9999999"/>
  </div>
</template>
  • 6-2.优化后:提高用户体验,使用defer让一部分逻辑先执行,另一部分逻辑后执行。
<template>
  <div>
    <h2>I'm an heavy page</h2>
    <template v-if="defer(2)">
      <Heavy v-for="n in 10" :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 mixin:

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

在这里插入图片描述

7.分批处理:

  • 7-1.优化前:
fetchItems ({ commit }, { items }) {
  commit('clearItems')
  commit('addItems', items)
}

在这里插入图片描述

  • 7-2.优化后:分批处理,提高画面渲染性能。
fetchItems ({ commit }, { items, splitCount }) {
  commit('clearItems')
  const queue = new JobQueue()
  splitArray(items, splitCount).forEach(
    chunk => queue.addJob(done => {
      // Commit array chunks on several frames
      requestAnimationFrame(() => {
        commit('addItems', chunk)
        done()
      })
    })
  )
  // Start and wait for all the jobs
  // to finish
  await queue.start()
}

在这里插入图片描述

8.非响应式数据:将不修改的数据冻结。或者将不需要响应的数据不放在data里面。

  • 8-1.优化前:
const data = items.map(
  item => ({
    id: uid++,
    data: item,
    vote: 0
  })
)
  • 8-2.优化后:非响应模式(非观察模式),显示声明为非响应式,不想让vue框架去观察data,提高数据响应效率。或者使用Object.freeze()冻结数据。
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
}

在这里插入图片描述

9.仅渲染可视化部分:

  • 9-1.优化前:
<div class="items no-v">
  <FetchItemViewFunctional
    v-for="item of items"
    :key="item.id"
    :item="item"
    @vote="voteItem(item)"
  />
</div>
  • 9-2.优化后:仅渲染可视化部分,批量渲染
<recycle-scroller
  class="items"
  :items="items"
  :item-size="24"
>
  <template v-slot="{ item }">
    <FetchItemView
      :item="item"
      @vote="voteItem(item)"
    />
  </template>
</recycle-scroller>

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值