Vue2性能优化

1.函数式组件

使用单文件定义函数式组件

设置functional即表示该组件为一个函数式组件

函数式组件不会有状态,不会有响应式数据,不会有生命周期钩子函数。可以把它当成把普通组件模板中的一部分 DOM 剥离出来,通过函数的方式渲染出来,是一种在 DOM 层面的复用。


2.子组件拆分

优化前:




优化后:




优化后的方式是把这个耗时任务 heavy 函数的执行逻辑用子组件 ChildComp 封装了,由于 Vue 的更新是组件粒度的,虽然每一帧都通过数据修改导致了父组件的重新渲染,但是 ChildComp 却不会重新渲染,因为它的内部也没有任何响应式数据的变化。所以优化后的组件不会在每次渲染都执行耗时任务,自然执行的 JavaScript 时间就变少了。

3.局部变量

优化前:




优化后:




主要是优化前后组件的计算属性 result 的实现差异,优化前的组件多次在计算过程中访问 this.base,而优化后的组件会在计算前先用局部变量 base 缓存 this.base,后面则直接访问 base变量。

每次访问 this.base 的时候,由于 this.base 是一个响应式对象,所以会触发它的 getter,进而会执行依赖收集相关逻辑代码

4.使用v-show

使用v-show复用DOM

优化前的组件代码如下:


优化后的组件代码如下:


用 v-show 指令替代了 v-if 指令来替代组件的显隐

当条件 props.value 的值变化的时候,会触发对应的组件更新,对于 v-if 渲染的节点,由于新旧节点 vnode 不一致,在核心 diff 算法比对过程中,会移除旧的 vnode 节点,创建新的 vnode 节点,那么就会创建新的 Heavy 组件,又会经历 Heavy 组件自身初始化、渲染 vnode、patch 等过程。

因此使用 v-if 每次更新组件都会创建新的 Heavy 子组件,当更新的组件多了,自然就会造成性能压力。

5.KeepAlive

使用 KeepAlive 组件缓存 DOM

优化前:


优化后:


在非优化场景下,每次点击按钮切换路由视图,都会重新渲染一次组件,渲染组件就会经过组件初始化,render、patch 等过程,如果组件比较复杂,或者嵌套较深,那么整个渲染耗时就会很长。

而在使用 KeepAlive 后,被 KeepAlive 包裹的组件在经过第一次渲染后,的 vnode 以及 DOM 都会被缓存起来,然后再下一次再次渲染该组件的时候,直接从缓存中拿到对应的 vnode 和 DOM,然后渲染,并不需要再走一次组件初始化,render 和 patch 等一系列流程,减少了 script 的执行时间,性能更好。

但是使用 KeepAlive 组件并非没有成本,因为它会占用更多的内存去做缓存,这是一种典型的空间换时间优化思想的应用。

6.Deferred features

使用 Deferred 组件延时分批渲染组件

优化前:


优化后:




Defer 的主要思想就是把一个组件的一次渲染拆成多次,它内部维护了 displayPriority 变量,然后在通过 requestAnimationFrame 在每一帧渲染的时候自增,最多加到 count。然后使用 Defer mixin 的组件内部就可以通过 v-if=“defer(xxx)” 的方式来控制在 displayPriority 增加到 xxx 的时候渲染某些区块了。

7.Time slicing

使用 Time slicing 时间片切割技术

优化前:

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()
      })
    })
  )
  await queue.start()
}

8.Non-reactive data

优化前:

const data = items.map(
  item => ({
    id: uid++,
    data: item,
    vote: 0
  })
)

优化后:

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.Virtual scrolling

优化前:

优化后代码如下:


  

你可能感兴趣的:(前端,计算机,vue.js)