相关文章
vue项目优化
减少重新渲染:
- 使用合适的 v-if 和 v-show 来控制组件的显示和隐藏,以减少不必要的重新渲染。
v-show的使用场景
保持元素状态:使用 v-show 可以保持元素的状态,当元素由隐藏状态切换到显示状态时,元素的状态(例如输入框中的内容)会被保留,而不会丢失。
渲染开销较大的元素:对于渲染开销较大的元素,使用 v-show 可以避免每次切换都要重新渲染元素的开销,从而提高性能。
需要 CSS 过渡效果的元素:由于 v-show 只是简单地通过 CSS 控制元素的显示和隐藏,所以可以很方便地与 CSS 过渡效果配合使用,实现元素的渐显效果。
路由优化
- 使用路由懒加载来按需加载路由组件,减少初始加载时的资源开销。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { createRouter, createWebHistory } from 'vue-router';
const routes = [ { path: '/', name: 'Home', component: () => import('./views/Home.vue') // 路由懒加载 }, { path: '/about', name: 'About', component: () => import('./views/About.vue') // 路由懒加载 } ];
const router = createRouter({ history: createWebHistory(), routes });
export default router;
|
使用异步组件和动态导入
- 将项目中的组件按需进行异步加载,使用 Vue 提供的异步组件和动态导入功能,以减少初始加载时的资源请求。
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
| <template> <div> <button @click="loadComponent">Load Component</button> <div v-if="showComponent"> <AsyncComponent/> </div> </div> </template>
<script> export default { data() { return { showComponent: false, AsyncComponent: null }; }, methods: { loadComponent() { import('./AsyncComponent.vue').then(module => { this.AsyncComponent = module.default; this.showComponent = true; }).catch(error => { console.error('Failed to load component:', error); }); } } }; </script>
|
组件粒度的性能优化
避免不必要的响应式数据
- 在 Vue 组件中尽量避免定义过多的响应式数据,因为每个响应式数据的变化都会触发重新渲染,影响性能。
避免过度使用计算属性和监听器
计算属性和监听器会在每次数据变化时重新计算,因此过度使用会增加性能开销。在必要时才使用计算属性和监听器,尽量减少不必要的计算。
优化列表渲染
对于大量数据的列表渲染,使用列表的虚拟化技术,如 vue-virtual-scroller、vue-virtual-scroll-list 等,减少页面渲染量,提升性能。
合理使用 Vuex 状态管理
在大型应用中合理使用 Vuex 进行状态管理,但不要滥用。避免将所有数据都放在 Vuex 中管理,只将需要共享和持久化的数据放在 Vuex 中。
使用 keep-alive 缓存组件
对于频繁切换的组件,可以使用 Vue 的 keep-alive 缓存组件实例,避免每次重新渲染,提高页面响应速度。
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
| <template> <div> <button @click="toggleComponent">Toggle Component</button> <keep-alive> <component :is="currentComponent"></component> </keep-alive> </div> </template>
<script> import ComponentA from './ComponentA.vue'; import ComponentB from './ComponentB.vue';
export default { data() { return { currentComponent: 'ComponentA' }; }, components: { ComponentA, ComponentB }, methods: { toggleComponent() { this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA'; } } }; </script>
|
使用 Vue.extend 动态创建组件
在需要动态创建大量相似的组件实例时,可以使用 Vue.extend 动态创建组件构造函数,提高组件的创建效率。
vue2.x
1 2 3 4 5 6 7 8 9 10
| var MyComponent = Vue.extend({ template: '<div>This is a dynamic component!</div>' });
var myComponentInstance = new MyComponent();
myComponentInstance.$mount('#app');
|
Vue 生命周期优化
合理使用 Vue 生命周期钩子函数,避免在生命周期函数中做过多的计算或 DOM 操作,减少不必要的性能开销。
使用Object.freeze冻结响应式数据
Vue 会通过 Object.defineProperty 对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要 Vue 来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间
1 2 3 4 5 6 7 8 9
| export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = Object.freeze(users); } };
|
事件的销毁
Vue 组件销毁时,会自动清理它与其它实例的连接,解绑它的全部指令及事件监听器,但是仅限于组件本身的事件。 如果在 js 内使用 addEventListene 等方式是不会自动销毁的,我们需要在组件销毁时手动移除这些事件的监听,以免造成内存泄露
1 2 3 4 5 6
| created() { addEventListener('click', this.click, false) }, beforeDestroy() { removeEventListener('click', this.click, false) }
|
v-for遍历必须为item添加key
因为 Vue 使用 key 来识别列表中的每个项,并且在列表发生变化时对比新旧节点,从而尽可能地高效更新 DOM。