当前位置:   article > 正文

Vue的性能优化常用的有哪些?_vue前端性能优化有哪些

vue前端性能优化有哪些


Vue的性能优化有哪些?

Vue 的性能优化涉及多个方面,包括编码阶段、SEO 优化、打包优化和用户体验。

编码阶段优化

1. 减少 data 中的数据

减少 data 的数据量可以降低应用的复杂度,避免不必要的性能开销。

  • 在Vue中,data对象中的数据会触发Vue的响应式系统,当数据发生变化时会更新相关的视图。
  • 减少data中的数据量可以降低应用的复杂度,减少不必要的性能开销。

假设在一个电子商务网站中,需要展示商品列表,每个商品需要显示图片、名称、价格等信息。在这种情况下,我们需要从后端获取大量商品数据,并在前端进行展示。

案例参考

在这个项目中,我们需要在前端展示大量商品信息,同时保持页面的流畅性和性能。

<template>
  <div>
    <div v-for="product in products" :key="product.id">
      <img :src="product.image" alt="product.name">
      <h3>{{ product.name }}</h3>
      <p>{{ product.price }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      products: [] // 这里存放了大量的商品数据
    };
  },
  created() {
    // 从后端获取商品数据并更新products数组
    // ...
  }
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在实际工作中,我们可以从后端获取大量的商品数据,但不一定所有的数据都需要在data中进行响应式处理。在这种情况下,我们可以使用Vue的响应式系统仅对需要在界面上展示的数据进行响应式处理,而不必将所有的数据都放到data中。

  • 通过减少data中的数据量,我们可以降低组件的复杂度,减少不必要的性能开销。
  • 在实际工作中,需要根据实际需求和数据量来决定哪些数据需要放在data中进行响应式处理,避免不必要的性能消耗。
避免响应所有数据
  • 在Vue中,data中的数据都会增加getter和setter,并且会收集watcher,这样会占用内存。
  • 不需要响应式的数据可以直接定义在实例上,避免不必要的性能开销。

在一个社交平台的消息列表中,需要展示用户的消息列表,每条消息包括内容、发送者、时间等信息。

案例参考

在这个项目中,我们需要在前端展示用户的消息列表,同时保持页面的流畅性和性能。

<template>
  <div>
    <div v-for="message in messages" :key="message.id">
      <p>{{ message.content }}</p>
      <p>{{ message.sender }}</p>
      <p>{{ message.time }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      messages: [] // 这里存放了大量的消息数据
    };
  },
  beforeCreate() {
    this.timer = null;
  }
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在这个案例中,我们需要在前端展示用户的消息列表。对于这种不需要进行响应式处理的数据,可以直接定义在实例上而不必放在data中,从而避免不必要的性能开销。

  • 避免将不需要响应式处理的数据放在data中,可以直接定义在实例上。
  • 在实际工作中,需要根据实际需求来判断哪些数据需要进行响应式处理,哪些数据可以直接定义在实例上,以避免不必要的性能开销。
总结

在编码阶段,减少data中的数据量,并避免将不需要响应式处理的数据放在data中,都是非常重要的性能优化方法。通过合理处理数据,可以降低组件的复杂度,减少不必要的性能开销,提高应用的性能和流畅性。

2. 避免同时使用 v-if 和 v-for

在同一元素上同时使用 v-if 和 v-for 会导致性能问题,需要避免这种情况。

在Vue中,同时在同一元素上使用v-if和v-for会导致性能问题。这是因为v-for遍历的优先级比v-if高,如果每次都需要遍历整个数组,将会影响速度。此外,在进行列表数据的遍历渲染时,需要为每个被遍历的元素添加一个唯一的key,这样可以帮助Vue.js内部机制精准找到该条列表数据,并在状态更新时更快地定位到diff。

假设在一个社交平台中,需要展示用户的帖子列表,同时需要根据用户权限判断是否显示帖子内容。

案例参考

在这个项目中,我们需要根据用户的权限判断是否显示帖子内容,并且需要遍历并展示帖子列表。

<template>
  <div>
    <div v-for="post in filteredPosts" :key="post.id">
      <h3>{{ post.title }}</h3>
      <p v-if="userHasPermission(post)">{{ post.content }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      posts: [
        { id: 1, title: 'Post 1', content: 'Content 1', userId: 1 },
        { id: 2, title: 'Post 2', content: 'Content 2', userId: 2 }
        // ... more posts
      ],
      currentUser: {
        id: 1
      }
    };
  },
  computed: {
    filteredPosts() {
      return this.posts.filter(post => post.userId === this.currentUser.id);
    }
  },
  methods: {
    userHasPermission(post) {
      // Check if the current user has permission to view the post
      // ...
      return hasPermission;
    }
  }
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

在这个案例中,我们遍历帖子列表并根据用户的权限判断是否显示帖子内容。我们使用v-for来遍历帖子列表,并在v-if中判断用户是否有权限查看帖子内容。

  • 避免同时在同一元素上使用v-if和v-for,因为v-for的优先级比v-if高,可能会影响速度。
  • 在进行列表数据的遍历渲染时,需要为每个被遍历的元素添加一个唯一的key,以帮助Vue.js内部机制更快地定位到diff。
总结

避免同时使用v-if和v-for是一个重要的性能优化方法,在实际开发中需要特别注意。合理使用v-if和v-for可以提高应用的性能和流畅性,同时确保列表数据的遍历和渲染能够高效地进行。

3. 事件代理

如果需要给 v-for 中的每项元素绑定事件,最好使用事件代理,提高性能。

4. 使用 keep-alive 缓存组件

对于单页面应用 (SPA),可以使用 keep-alive 缓存组件,提高页面切换时的性能。

5. 使用 v-if 替代 v-show

在更多的情况下,使用 v-if 而不是 v-show,因为 v-show 会一直渲染,而 v-if 只在条件满足时才会渲染。

在Vue中,v-if和v-show都是用于控制元素的显示与隐藏。它们之间的主要区别在于:

  • v-if:根据条件动态地向DOM树内添加或者删除DOM元素。它是一种"懒加载"方式,只在条件满足时才会渲染相关的DOM元素。
  • v-show:通过设置DOM元素的display样式属性来控制元素的显隐。它是基于CSS的切换,DOM元素一直被渲染,只是通过样式控制是否显示出来。

假设在一个电商网站中,需要根据用户的选择展示不同的商品推荐信息,同时需要在用户进行搜索时实时展示搜索结果。

案例参考

在这个项目中,我们需要根据用户的选择展示不同的商品推荐信息,同时在用户进行搜索时实时展示搜索结果。

<template>
  <div>
    <div v-if="showRecommendation">
      <h3>Recommended Products</h3>
      <!-- Show recommended products -->
    </div>
    <div>
      <input type="text" v-model="searchInput">
      <ul v-show="showSearchResults">
        <li v-for="result in searchResults" :key="result.id">{{ result.name }}</li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showRecommendation: true,
      searchInput: '',
      searchResults: [],
      showSearchResults: false
    };
  },
  watch: {
    searchInput() {
      // Perform search based on input
      // Update searchResults and showSearchResults
      // ...
    }
  }
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

在这个案例中,我们使用v-if来根据条件展示推荐商品信息,而在搜索时使用v-show来实时展示搜索结果。这样可以根据具体需求选择合适的指令,以提高页面的性能和用户体验。

  • v-if适合条件不太可能改变的情况,因为它是懒加载的,只在条件第一次变为真时才开始渲染。
  • v-show适合条件频繁切换的情况,因为它是基于CSS的切换,DOM元素一直被渲染,只是通过样式控制是否显示出来。
总结

合理使用v-if和v-show可以根据具体场景提高页面性能和用户体验。在开发中,根据条件的变化频率和渲染开销来选择合适的指令,有助于优化页面的渲染和响应速度。

6. 保证 key 值的唯一性

在使用 v-for 渲染列表时,保证 key 的唯一性,可以帮助 Vue 更高效地更新 DOM。

7. 使用路由懒加载和异步组件

按需加载路由和组件,减少首次加载的资源体积,提高页面加载速度。

8. 防抖和节流

合理使用防抖和节流来控制事件的频繁触发,提高性能。

9. 第三方模块按需导入

只导入需要使用的第三方模块,减少不必要的资源加载。

10. 长列表滚动到可视区域动态加载

对于大型列表,可以只加载可视区域内的内容,而不是一次性加载所有数据。

在处理大型列表时,为了提高性能,可以只加载可视区域内的内容,而不是一次性加载所有数据。为了实现这一目的,可以采取以下优化措施:

  • 分段加载:仅渲染视窗可见的数据,通过监听滚动事件来动态加载数据,从而减少初始渲染所需的时间和资源消耗。
  • 函数节流:对于滚动事件等频繁触发的操作,可以通过函数节流来控制操作的执行频率,避免过多的计算和渲染。
  • 减少驻留的VNode和Vue组件:避免在长列表中过多使用Vue组件,可以手动创建虚拟DOM来减少对象引用,从而降低内存消耗。

假设在一个社交平台中,需要展示用户的动态信息列表,同时需要在滚动到可视区域时动态加载更多的动态信息。

案例参考

在这个项目中,我们需要展示用户的动态信息列表,并在滚动到可视区域时动态加载更多的动态信息,以提高页面加载性能和用户体验。

<template>
  <div ref="listContainer" @scroll="handleScroll">
    <div v-for="item in visibleItems" :key="item.id">
      <!-- Render visible items -->
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      allItems: [], // All dynamic information items
      visibleItems: [], // Items currently visible in the viewport
      lastVisibleIndex: 0 // Index of the last visible item
    };
  },
  mounted() {
    // Fetch initial batch of data
    // ...
    this.updateVisibleItems();
  },
  methods: {
    handleScroll() {
      // Throttle the scroll event to avoid frequent function calls
      // ...
      this.updateVisibleItems();
    },
    updateVisibleItems() {
      // Calculate the visible items based on scroll position
      // ...
      this.visibleItems = this.allItems.slice(0, this.lastVisibleIndex + 1);
    },
    fetchMoreData() {
      // Fetch more data when the user scrolls to the end of the list
      // ...
      // Update allItems and then call updateVisibleItems
      // ...
    }
  }
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

在这个案例中,我们通过监听滚动事件来动态更新可视区域内的数据,从而实现长列表的分段加载。在滚动到可视区域时,动态加载更多的数据以保持页面的流畅性。

  • 对滚动事件进行函数节流,以避免频繁触发函数调用。
  • 使用手动创建虚拟DOM来减少对象引用,避免过多的内存消耗。
总结

通过分段加载、函数节流和减少驻留的VNode和Vue组件等优化方法,可以提高长列表的性能表现,同时降低页面初始化和滚动时的资源消耗。在实际开发中,根据具体需求选择合适的优化方案,有助于提升用户体验和页面性能。

11. 图片懒加载

延迟加载图片,减少页面初次加载时的请求和资源消耗。

12. 函数式组件

不需要像普通组件那样经过额外的初始化,从而避免了相关操作带来的性能消耗。

函数式组件是Vue中一种特殊的组件,它不包含状态和实例,也就是说它不支持响应式,而且无法通过"this"关键字引用自身。因为函数式组件没有状态,所以它们不需要像Vue的响应式系统一样需要经过额外的初始化,从而避免了相关操作带来的性能消耗。尽管函数式组件无法知道自身状态何时发生变化,但仍然能够对传入的props的变化做出响应式改变。

假设在一个社交平台的消息列表中,需要展示用户的消息列表,每条消息包括内容、发送者、时间等信息。

案例参考

在这个项目中,我们需要在前端展示用户的消息列表,同时保持页面的流畅性和性能。考虑到消息列表是静态的,不需要响应式处理,因此适合使用函数式组件。

<template functional>
  <div>
    <p>{{ props.message.content }}</p>
    <p>{{ props.message.sender }}</p>
    <p>{{ props.message.time }}</p>
  </div>
</template>

<script>
export default {
  functional: true,
  props: {
    message: {
      type: Object,
      required: true
    }
  }
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这个案例中,我们定义了一个函数式组件来展示用户的消息列表。由于消息列表是静态的,不需要响应式处理,因此我们使用了functional属性,并通过props来传入消息数据。

  • 函数式组件适合展示静态内容,比如展示组件中的按钮、标签、卡片等,以及整个页面是静态文本的情况。
  • 在高阶组件中,函数式组件也可以用于接收一个组件作为参数,返回一个被包装过的组件。
总结

函数式组件在Vue中有着特殊的作用,特别适合展示静态内容和作为高阶组件。通过使用函数式组件,我们可以避免不必要的性能开销,提高应用的性能和流畅性。

SEO 优化

1. 预渲染和服务端渲染 (SSR)

通过预渲染或服务端渲染,可以提高搜索引擎对页面的抓取效率和用户体验。

打包优化

1. 压缩代码:

压缩 JavaScript、CSS 和 HTML 代码,减小文件体积,提高加载速度。

2. Tree Shaking 和 Scope Hoisting:

利用工具去除无用代码,并合并模块,减小打包体积。

3. 使用 CDN 加载第三方模块

使用 CDN 加速第三方模块的加载,减轻服务器压力,提高加载速度。

4. 多线程打包和 splitChunks 抽离公共文件

使用多线程打包工具和抽离公共文件,提高打包效率和加载速度。

5. SourceMap 优化

在生产环境中合理配置 SourceMap,以便更好地进行错误追踪和调试。

用户体验优化

1. 骨架屏

在页面加载过程中,使用骨架屏提供一种占位符,提高用户体验。

2. PWA (渐进式 Web 应用)

利用 PWA 技术,使应用具有更好的离线访问和缓存能力。

3. 缓存优化和服务端开启 Gzip 压缩

合理使用客户端和服务端缓存,以及开启服务器端的 Gzip 压缩,提高加载速度和用户体验。

其他优化方法

1. 避免过深的对象层级

避免对象层级过深,以减少性能损耗。

2. 合理使用 Object.freeze() 冻结数据

对于不需要响应式的数据,可以使用 Object.freeze() 冻结数据,提高性能。

3. 区分使用场景的 v-if 和 v-show

根据具体需求,合理选择使用 v-if 或 v-show。

4. 合理使用 computed 和 watch

根据数据变化的不同需求,合理选择使用 computed 或 watch。
在Vue中,computed和watch都是用于处理数据变化的工具。它们分别适用于不同的场景:

  • computed:计算属性,依赖其他属性值,并且computed的值有缓存。只有它依赖的属性值发生改变,下一次获取computed的值时才会重新计算computed的值。
  • watch:更多的是用于观察数据的变化,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。适合执行异步或开销较大的操作。

假设在一个电子商务网站中,需要展示商品列表,同时需要根据用户的筛选条件动态显示不同的商品信息。

案例参考

在这个项目中,我们需要根据用户的筛选条件动态显示不同的商品信息,同时需要进行数值计算,比如价格的折扣计算。

<template>
  <div>
    <select v-model="category">
      <option value="electronics">Electronics</option>
      <option value="clothing">Clothing</option>
    </select>
    <div v-for="product in filteredProducts" :key="product.id">
      <h3>{{ product.name }}</h3>
      <p>Price: {{ discountedPrice(product.price) }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      category: 'electronics',
      products: [
        { id: 1, name: 'Laptop', category: 'electronics', price: 1000 },
        { id: 2, name: 'T-shirt', category: 'clothing', price: 20 }
        // ... more products
      ]
    };
  },
  computed: {
    filteredProducts() {
      return this.products.filter(product => product.category === this.category);
    }
  },
  methods: {
    discountedPrice(price) {
      // perform some calculations for discount
      // ...
      return discountedPrice;
    }
  },
  watch: {
    category(newVal, oldVal) {
      // perform some asynchronous or heavy operation based on category change
      // ...
    }
  }
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

在这个案例中,我们使用computed来根据用户选择的类别筛选商品,并使用watch来监听用户的类别变化。当用户选择的类别发生变化时,watch中的回调函数可以执行一些异步或开销较大的操作。

  • 在进行数值计算并且依赖于其他数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值时都要重新计算。
  • 当需要在数据变化时执行异步或开销较大的操作时,应该使用watch,可以限制执行操作的频率,并在得到最终结果前设置中间状态。
总结

合理使用computed和watch可以根据数据变化的不同需求进行处理,从而提高应用的性能和流畅性。computed适合进行数值计算,而watch适合执行异步或开销较大的操作。通过合理选择使用computed或watch,我们可以更好地响应数据变化,提高应用的用户体验。

5. 避免内存泄漏

在组件销毁后,及时清理全局变量和事件,防止内存泄漏。

持续学习总结记录中,回顾一下上面的内容:
Vue性能优化包括减少数据量、合理使用v-if和v-for、懒加载组件和图片、优化路由、缓存、压缩代码、骨架屏等。同时需注意对象层级不宜过深、合理使用computed和watch、避免内存泄漏。整合这些方法可以显著提升Vue应用性能。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/919548
推荐阅读
相关标签
  

闽ICP备14008679号