当前位置: 首页 > web >正文

Vue常用优化

使用key

帮助 Vue 高效更新虚拟 DOM

<!-- 推荐:使用唯一ID -->
<div v-for="item in items" :key="item.id"><!-- 避免:使用索引作为key(除非列表简单且无状态) -->
<div v-for="(item, index) in items" :key="index">
使用冻结对象

冻结对象不会被响应化

// 对于纯展示的大数据对象
this.largeData = Object.freeze(bigData);// 冻结数组避免意外修改
this.staticList = Object.freeze([...]);
使用函数式组件

https://cn.vuejs.org/guide/extras/render-function.html#functional-components

减少javaScript执行时间,渲染时间,内存占用大小

没有在像其他组件内部new VueComponent 创建Vue组件实例,只做纯渲染

适用场景:纯展示组件,无状态、无实例、无生命周期

export default {functional: true,props: ['value'],render(h, { props }) {return h('div', props.value)}
}
使用计算属性

如果模板中某个数据会使用多次,并且该数据是通过计算得到的,使用计算属性以缓存它们

computed: {filteredItems() {return this.items.filter(item => item.active);}
}
非实时绑定的表单项

对于表单输入,默认的v-model会监听@input事件,每当输入框的值发生变化时立即触发,导致每次输入都触发数据更新和视图重渲染。可以通过以下方式优化:

  • 使用v-model.lazy:监听change事件,当输入框失去焦点且值发生变化时触发,减少更新频率。

    <input v-model.lazy="searchQuery" />  
    
  • 手动绑定值和事件:完全控制数据更新时机。

    <input :value="searchQuery" @change="updateQuery($event.target.value)" />
    

注意:这可能导致数据与表单控件暂时不同步,需根据具体需求权衡使用。

<!-- 减少输入时的频繁更新 -->
<input v-model.lazy="searchQuery"><!-- 手动实现(更灵活控制) -->
<input :value="searchQuery" @change="updateSearch">
保持对象引用稳定

在绝大部分情况下,vue 触发 rerender 的时机是其依赖的数据发生变化

若数据没有发生变化,哪怕给数据重新赋值了,vue也是不会做出任何处理

// 不推荐:会导致引用变化
this.obj = { ...this.obj, value: newValue };// 推荐:保持引用不变
this.obj.value = newValue;
this.$set(this.obj, 'value', newValue);

下面是vue判断数据没有变化的源码

function hasChanged(x, y){if (x === y){return x === 0 && 1 / x !== 1 / y} else {return x === x || y === y}
}

因此,如果需要,只要能保证组件的依赖数据不发生变化,组件就不会重新渲染。

  • 原始类型:直接赋值即可。
  • 对象类型:避免直接修改原对象,使用合并或替换策略。
使用v-show替代v-if

对于频繁切换显示状态的元素,使用v-show可以保证虚拟dom树的稳定,避免频繁的新增和删除元素,特别是对于那些内部包含大量dom元素的节点,这一点极其重要

<!-- 适合频繁切换的场景 -->
<HeavyComponent v-show="active" /><!-- 适合运行时条件很少改变的场景 -->
<HeavyComponent v-if="shouldRender" />
使用延迟装载(defer)

JS传输完成后,浏览器开始执行JS构造页面。

但可能一开始要渲染的组件太多,不仅JS执行的时间很长,而且执行完后浏览器要渲染的元素过多,从而导致页面白屏

可以通过延迟装载组件,让组件按照指定的先后顺序依次一个一个渲染出来

延迟装载是一个思路,本质上就是利用 requestAnimationFrame 事件分批渲染内容,它的具体实现多种多样

methods: {deferRender() {requestAnimationFrame(() => {this.showComponent = true;});},
},
mounted() {this.deferRender();
},
function renderBatch(components) {requestAnimationFrame(() => {components.forEach(component => component.render());});
}
使用keep-alike

对于频繁切换的动态组件,使用<keep-alive>可以缓存组件状态,减少重新渲染和数据获取的开销。

  • 配合 include/exclude 精确控制
<keep-alive :include="['ComponentA', 'ComponentB']"><component :is="currentComponent"></component>
</keep-alive>

注意事项:

  • 适用于需要保留状态的组件,如表单、数据列表等。
  • 对于不需要缓存的组件,可以使用exclude属性或动态条件控制。
长列表优化

处理大量数据渲染时,常规的v-for可能导致性能问题

  • 虚拟滚动:对于超长列表,只渲染可视区域内的少量元素,其他部分使用占位符

    • 第三方库:如vue-virtual-scroller
    • 自定义实现:监听滚动事件,动态计算并渲染可见元素。
  • 分页/懒加载:按需加载和渲染

  • 冻结非可视区域数据

    // 只响应化当前可视区域的数据
    this.visibleItems = Object.freeze(items.slice(start, end));
    
图片懒加载

使用 IntersectionObserver 或第三方库(如 vue-lazyload)实现图片懒加载。

<img v-lazy="imageSrc" alt="Lazy Loaded Image">
SSR(服务端渲染)

提升首屏加载速度,改善 SEO。

  • 使用 Nuxt.js 或 Vue SSR 提供的服务端渲染能力。
  • 配合 CDN 缓存静态页面。
自定义指令优化

复杂 DOM 操作使用自定义指令

打包优化
  • 路由懒加载

    const Data = () => import(/* webpackChunkName: "Data" */ './Data.vue')
    
  • 按需引入

    // 例如ElementUI
    import { Button, Select } from 'element-ui';
    
  • Tree-shaking

    移除未使用的代码

    • ES6模块语法:使用importexport,便于打包工具分析依赖。

    • 避免副作用导入:确保只导入需要的模块部分。

  • 压缩

    代码压缩、静态资源压缩(图片压缩工具imagemin等)

    启用Terser插件,压缩JavaScript代码,减小体积

    // vue.config.js
    module.exports = {productionSourceMap: false,configureWebpack: {optimization: {minimize: true}}
    }
    
  • 使用轻量级替代方案:例如,使用lodash-es代替完整的lodash,减少包大小。

  • 分析工具

    vue-cli-service build --report
    
http://www.xdnf.cn/news/3892.html

相关文章:

  • d3_v7绘制折线图
  • 启发式算法-遗传算法
  • C++ - 类和对象 #类的默认成员函数 #构造函数 #析构函数 #拷贝构造函数 #运算符重载函数 #赋值运算符重载函数
  • AI 入门:关键概念
  • 高等数学同步测试卷 同济7版 试卷部分 上 做题记录 第四章 不定积分同步测试卷 B卷
  • n8n 快速入门1:构建一个简单的工作流
  • 强化学习机器人模拟器——GridWorld:一个用于强化学习的 Python 环境
  • unorder_map/set的底层实现---C++
  • ESP32S3 多固件烧录方法、合并多个固件为单一固件方法
  • LangChain4J-XiaozhiAI 项目分析报告
  • 线程间通信--线程间顺序控制
  • C++类_局部类
  • 安装与配置Go语言开发环境 -《Go语言实战指南》
  • C#与西门子PLC通信:S7NetPlus和HslCommunication使用指南
  • JavaWeb:SpringBootWeb快速入门
  • 五、shell脚本--函数与脚本结构:搭积木,让脚本更有条理
  • JavaScript 中的 Proxy 与 Reflect 教程
  • 比特、字节与布尔逻辑:计算机数据存储与逻辑运算的底层基石
  • PMP-第四章 项目整合管理(一)
  • 享元模式(Flyweight Pattern)
  • MOS管极间电容参数学习
  • spring中的@ComponentScan注解详解
  • stm32week14
  • 主机电路安全防护系统哪个厂家做
  • 招聘绩效效果评估方案与优化路径
  • 35、C# 中的反射(Reflection)
  • 深入理解 Spring MVC:DispatcherServlet 与视图解析机制​
  • 快速弄懂POM设计模式
  • 1991年-2023年 上市公司-重污染企业数据 -社科数据
  • GitHub 趋势日报 (2025年05月03日)