美文网首页
vue性能优化

vue性能优化

作者: 37手游技术部 | 来源:发表于2021-07-06 14:28 被阅读0次

文章目录

1.代码优化

2.项目优化

3.其它优化

4.总结

本文主要针对的是 vue 2.x 版本的性能优化,并且从代码优化 和 其他的优化去讲下在项目开发时应该注意的优化事项。

首先从项目代码层面方面

1.代码优化

v-if / v-show

这两个指令在不同场景的使用下,会有不同的性能损耗情况,首先简单了解下两者的区别。

  • v-if 指令在编译阶段就会编译成一个三元运算符,通过条件进行渲染。当条件的值变化时,会触发对应的组件更新,即会经过 diff 算法, 组件初始化、渲染 vnode、patch等过程。
  • v-show 指令相比于 v-if 的优势就是它在更新阶段仅仅更新了 DOM 的显隐,少去了很多性能开销的操作。但是初始化的时候会把所有条件节点都渲染出来
<!-- v-if -->
<template>
    <section>
    <p v-if="props.value">Hello World!</p>
    <p v-else>Vue yyds</p>
  </section>
</template>

<!-- v-show -->
<template>
    <section>
    <p v-show="props.value">Hello World!</p>
    <p v-show="!props.value">Vue yyds</p>
  </section>
</template>
  • 使用场景:

初始化阶段: v-if 性能优于 v-show
频繁更新阶段: v-show 性能优于 v-if

v-for 和 v-if

避免把这两个指令放在同一个节点

因为 v-for 指令的优先级比 v-if 高,所以两个指令混用的话会导致每次节点render的结果都带上了条件渲染。当数据量和节点复杂的时候,就会有明显的性能差。

当我们要循环节点和条件判断的时候,我们可以先对数据进行处理后再进行 v-for 渲染,如下例子:

<!-- bad -->
<div v-for="item in list" v-if="item.count > 10" :key="item.id">{{item.name}}</div>

<!-- good -->
<div v-for="item in filters" :key="item.id">{{item.name}}</div>

computed: {
  filters () {
    return this.list.filter(item => item.count > 10)
  }
}

从上面例子不难看出,每个 v-for 节点处就加了 key 唯一标识,这也是提升性能的一个小点。使用 key 时,vue会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

keep-alive

部分场景可以使用 keep-alive 进行组件缓存

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

v-slot:slotName / slot="slotName"

vue 2.6 版本,可以使用 v-slot:slotName 的语法代替 slot="slotName"

  • 旧的写法在更新时多了一个父组件更新的过程,而新的写法由于直接更新子组件,就会更加高效,性能更好,所以推荐始终使用语法 v-slot:slotName
函数式组件

vue 2.x 的版本,需要DOM层复用的情况且场景相对简单时,可以用 函数式组件 代替普通组件

函数式组件生成的是普通的 vnode,不会存在递归子组件的过程,所以会减少一定程度的性能开销

场景:我在多个页面都复用了一个页面渲染的组件,不需要一些复杂的操作,只需要根据传参进行条件渲染或者循环渲染等、就可以用如下的例子去进行组件的编写

<!-- 函数式组件 -->
<template functional>
  <section>
    <div v-if="props.value">Hello World</div>
    <div v-else>Hi~</div>
    <ul>
      <li v-for="item in props.list" :key="item.id">{{item.name}}</li>
    </ul>
  </section>
</template>
子组件拆分

除开代码维护的层面,从性能方面,组件的拆分也是有好处的。

  • 因为vue 的更新是组件力度,如果组件中有数据发生变化,就会执行 render 函数生成新的 vnode 和旧的 vnode 进行 diff。哪怕这个数据只影响到一个元素渲染,其他元素也需要在 diff 过程中进行比较。极端情况是假设这个大组件里面有个倒计时。
  • 如果组件拆分得当的话,大部分的数据改动只会影响到子组件本身进行 diff ==> 渲染。所以合理得对这种大组件进行拆分,应用的更新效率会更高。

例如:

<!-- 拆分前 -->
<template>
  <div :style="{ opacity: number / 300 }">
    <div>{{ heavy() }}</div>
  </div>
</template>

<script>
export default {
  props: ['number'],
  methods: {
    heavy () {
      const n = 100000
      let result = 0
      for (let i = 0; i < n; i++) {
        result += Math.sqrt(Math.cos(Math.sin(42)))
      }
      return result
    },
  },
}
</script>


<!-- 拆分后 -->
<template>
  <div :style="{ opacity: number / 300 }">
    <ChildComp/>
  </div>
</template>

<script>
export default {
  components: {
    ChildComp: {
      methods: {
        heavy () {
          const n = 100000
          let result = 0
          for (let i = 0; i < n; i++) {
            result += Math.sqrt(Math.cos(Math.sin(42)))
          }
          return result
        },
      },
      render (h) {
        return h('div', this.heavy())
      },
    },
  },
  props: ['number'],
}
</script>
响应式数据优化
data的优化

vue 在组件实例初始化的时候会对data进行响应式处理,能够减少一个数据就是减少一点点的性能开销。而且一些常量数据不应该在data里面进行定义,简单总结为以下三点:

  • 减少无用的data数据

  • 减少数据被observer

  • 数据尽量扁平化

局部变量缓存响应式数据

先直接看对比代码

// 优化前
// ··········
computed: {
  base () {
    return 42
  },
    result () {
      let result = this.start
      for (let i = 0; i < 1000; i++) {
        result += Math.sqrt(Math.cos(Math.sin(this.base))) + this.base * this.base + this.base + this.base * 2 + this.base * 3
      }
      return result
    },
}

// 优化后
// ·········
computed: {
  base () {
    return 42
  },
    result ({ base, start }) {
      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
    },
}

优化前每次调用 this.base 的时候,由于它是个响应式数据,每次都会调用都会触发它的 getter,进而执行依赖收集等逻辑。

优化后先把 this.base 缓存到局部变量,后面重复调用的时候就不会频繁的触发到 getter 的逻辑处理

computed

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 数据 还没有发生改变,多次访问 计算属性会立即返回之前的计算结果,可以极大提升性能。

例如:

<template>
  <div>{{count}}</div>
</template>
<script>
  export default {
    computed: {
      count () {
      let result
      // 复杂的计算操作
      return result
      }
    }
  }
</script>

2.项目优化

路由懒加载

在vue-router的配置文件里,定义一个能够被 Webpack 自动代码分割的异步组件

const Hello = () => import('//hello.vue')
const router = new VueRouter({
  routes: [
    { path: '/hello', component: Hello },
    { path: '/world', component: import('//world.vue') }
  ]
})
组件按需加载

element-ui 为例子,有些项目用ui组件库的时候使用的并不多,可以按需加载适当优化项目的体积

import {Button} from 'element-ui'

Vue.use(Button)

3.其它优化

1.图片懒加载
2.节流 / 防抖
3.长列表的虚拟滚动

4.总结

1.减少没必要的渲染机制
2.减少全量加载,适当的懒加载
3.正确的使用vue的每个api,本身vue这个框架就对性能方面做了很多处理,正常使用就不会出现性能瓶颈

相关文章

  • vue 性能优化点

    vue项目中,经常会遇到一些性能优化点,以下就是我在工作中,总结的优化点 vue 性能优化点 1,路由懒加载 2,...

  • Vue笔记六:Vue项目的性能优化之路

    Vue笔记六:Vue项目的性能优化之路 我最近也经常面试外包同事。面试的时候,总会有个问题,“你说一下性能优化的手...

  • Vue3和Vue2的区别

    vue3 新增的亮点 Performance 性能优化 Tree-shaking 支持摇树优化 Compositi...

  • sammary

    vue-diff算法 react 性能优化 diff算法 ,局部更新DOMshouldComponentUpdat...

  • react shouldComponentUpdate

    对比vue,性能优化对react更加重要,shouldComponentUpdate又是react中性能重要的一个...

  • [性能优化]Webpack篇

    参考文章:Vue 项目性能优化 — 实践指南(网上最全 / 详细) Webpack 对图片进行压缩 在 vue 项...

  • 【前端性能优化】vue性能优化

    一、template v-show,v-if 用哪个?第一个维度是权限问题,只要涉及到权限相关的展示无疑要用 v-...

  • vue 性能优化

    前言 一般来说,你不需要太关心vue的运行时性能,它在运行时非常快,但付出的代价是初始化时相对较慢。在最近开发的一...

  • Vue性能优化

    性能优化的手段 目标:降低打包后文件大小,提高首屏加载速度 手段: 1.懒加载 运用懒加载则可以将路由对应的页面组...

  • vue性能优化

    1、基础优化 针对HTML、CSS、JS 做第一步优化。对于vue文件中,我们优化的就是tempalte、styl...

网友评论

      本文标题:vue性能优化

      本文链接:https://www.haomeiwen.com/subject/yqbbultx.html