10 个 Vue 3 性能飙升技巧

更新日期: 2025-08-23阅读: 25标签: 性能

技巧 #1:用 shallowreactive 代替 reactive —— 节能模式

问题: 你是否曾遇到过这样的情况:仅仅改变了一个小小的对象属性,却导致整个组件重新渲染?这是因为 vue 3 的 reactive 默认使用深度响应式,这在处理大型数据集时会严重影响性能。

解决方案: 使用 shallowReactive!它只追踪对象顶层的属性变更,就像是为响应式系统开启了“省电模式”。这对于复杂的对象来说是完美的解决方案。

import { shallowReactive } from"vue";

// 使用 shallowReactive 创建一个仅顶层属性为响应式的对象
const userInfo = shallowReactive({
name: "前端专家",
address: { city: "", street: "" }, // 嵌套对象
hobbies: ["编程", "调试"],
});

// ✅ 顶层属性的变更会触发更新
userInfo.name = "Vue 高手";

// ❌ 嵌套对象属性的变更不会触发更新,从而避免了不必要的渲染
userInfo.address.city = "旧金山";

为何如此: 对于重量级的数据结构(如表格数据、api 响应),shallowReactive 能大幅减少不必要的重渲染。这是 Vue 3 优化中 必备 的技巧。


技巧 #2:使用 toRefs 实现 Ref 解构魔法

问题: 厌倦了手动从响应式对象中解构属性吗?(例如 const name = state.name)

解决方案:toRefs 能立即将一个响应式对象的每个属性都转换成独立的 ref。

import { reactive, toRefs } from "vue";

// 创建一个响应式对象
const user = reactive({ name: "Jane", age: 30 });

// 使用 toRefs 将对象的属性解构为独立的 ref
const { name, age } = toRefs(user);

// ✅ 现在可以像 ref 一样直接修改值,并触发响应式更新
name.value = "Doe";

为何如此: 它能让你的模板代码更简洁(可以直接使用 {{ name }} 而不是 {{ user.name }}),并遵循 DRY(Don't Repeat Yourself)原则。这是提升 Vue 3 代码优雅性的 关键


技巧 #3:使用 watchEffect 进行智能侦听

问题: 对 watch 需要立即执行回调或侦听多个数据源时的繁琐配置感到烦恼吗?

解决方案:watchEffect 会自动追踪其依赖,并在依赖变更后重新运行回调函数

import { ref, watchEffect } from "vue";

const count = ref(0);
const double = ref(0);

// watchEffect 会立即执行一次,然后自动追踪其内部用到的响应式依赖(这里是 `count`)
watchEffect(() => {
  // 当 count 的值变化时,这个函数会自动重新执行
  double.value = count.value * 2;
});

// 增加 count 的值,上面的 watchEffect 回调将会被触发
count.value++;

为何如此: 非常适合处理表单联动、派生状态计算和数据缓存等场景


技巧 #4:Suspense —— 让异步加载如丝般顺滑

问题: 加载异步组件时,用户会看到恼人的白屏吗?

解决方案: 使用 <Suspense> 组件优雅地处理加载状态。

<template>
  <Suspense>
    <!-- #default 插槽:当异步组件加载完成时显示 -->
    <template #default>
      <AsyncComponent />
    </template>

    <!-- #fallback 插槽:在异步组件加载期间显示的“加载中”UI -->
    <template #fallback>
      <p>全力加载中...</p>
    </template>
</Suspense>
</template>

<script setup>
import { defineAsyncComponent } from "vue";

// 使用 defineAsyncComponent 定义一个异步组件
const AsyncComponent = defineAsyncComponent(() => import("./AsyncComponent.vue"));
</script>

为何如此: 在异步操作期间提供无缝的用户体验。这是提升前端用户体验(UX)的 关键


技巧 #5:Teleport —— 随心所欲地渲染!

问题: 需要将模态框(Modal)或菜单(Menu)渲染到组件树之外的 dom 位置(如 <body>)吗?

解决方案:<Teleport> 可以将内容“传送”到 DOM 中的任何目标节点。

<template>
  <button @click="show = true">打开模态框</button>

<!-- 使用 Teleport 将内部内容传送到 body 标签下 -->
<Teleport to="body">
    <p
      v-if="show"
      class="modal"
    >
      <!-- 这个 p 会被渲染在 <body> 的直接子节点中 -->
      这是一个模态框
      <button @click="show = false">关闭</button>
    </p>
</Teleport>
</template>

为何如此: 完美解决了 z-index 层级问题和 css 作用域限制。这是处理 Vue 3 组件布局的 秘密武器


技巧 #6:v-copy 指令 —— 一键复制

问题: 是否在多个地方重复编写 document.execCommand('copy') 的逻辑?

解决方案: 创建一个可复用的自定义指令。

// 在 main.js 或插件文件中定义一个全局自定义指令
app.directive("copy", {
// 当指令绑定到元素上时触发
  mounted(el, binding) {
    el.addEventListener("click", () => {
      // 创建一个临时的 textarea 用于执行复制操作
      const textarea = document.createElement("textarea");
      // binding.value 是指令绑定的值,即 'Text to copy'
      textarea.value = binding.value;
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand("copy");
      // 操作完成后移除临时元素
      document.body.removeChild(textarea);
      alert("已复制!");
    });
  },
});
<!-- 在组件中直接使用指令 -->
<button v-copy="'需要复制的文本'">点我复制</button>

为何如此: 用一行代码实现逻辑复用,极大提升开发效率


技巧 #7:Pinia 插件 —— 为状态管理增添超能力

问题: 复杂的 Pinia store 是不是变得越来越混乱?

解决方案: 使用插件来扩展 store 的功能。

// 插件:为所有 store 添加一个 $reset 方法
const resetPlugin = ({ store }) => {
// $initialState 是我们自定义添加的属性,用于存储初始状态
const initialState = JSON.parse(JSON.stringify(store.$state));
  store.$reset = () => store.$patch(initialState);
};

// 创建 Pinia 实例并使用插件
const pinia = createPinia();
pinia.use(resetPlugin);

// 在组件中使用
const userStore = useUserStore();
userStore.$reset(); // 调用插件添加的自定义方法!

为何如此: 集中管理跨 store 的通用逻辑,让你的 Vue 3 状态管理水平更上一层楼


技巧 #8:v-memo —— 为列表渲染涡轮增压

问题: 大型列表不必要的重新渲染导致页面卡顿?

解决方案:v-memo 可以根据依赖项缓存 VNode。

<ul>
  <li
    v-for="item in items"
    :key="item.id"
    <!-- v-memo 接收一个依赖数组 -->
    <!-- 只有当 item.id 或 item.status 变化时,这个 li 才会重新渲染 -->
    v-memo="[item.id, item.status]"
  >
    {{ item.name }} - {{ item.status }}
  </li>
</ul>

为何如此: 对表格和大数据集至关重要。这是 Vue 3 性能优化中的 游戏规则改变者


技巧 #9:useIntersectionObserver —— 智能懒加载

问题: 页面因为加载过多图片而变得缓慢?

解决方案: 使用 VueUse 库中的组合式函数(Composable)实现懒加载。

<script setup>
import { ref } from'vue';
import { useIntersectionObserver } from'@vueuse/core';

// 创建一个 ref 来引用目标元素
const target = ref(null);
// 一个 ref 用于追踪元素是否可见
const isVisible = ref(false);

// 设置 Intersection Observer
useIntersectionObserver(
  target, // 监听的目标元素
  ([{ isIntersecting }]) => {
    // 当元素进入视口时,isIntersecting 会变为 true
    if (isIntersecting) {
      isVisible.value = true;
    }
  },
);
</script>

<template>
  <img
    ref="target"
    <!-- 仅当元素可见时才设置 src 属性,从而实现懒加载 -->
    :src="isVisible ? 'real-image-url.jpg' : 'placeholder.png'"
    alt="懒加载图片"
  >
</template>

为何如此: 优化资源加载,seo 和用户体验都堪称完美


技巧 #10:自定义 Hooks (Composables) —— 终极复用性

问题: 总是在不同组件间复制粘贴表单验证或数据请求的逻辑?

解决方案: 将逻辑封装在组合式函数(Composables)中。

// composables/useFormValidation.js

import { ref } from"vue";

exportdefaultfunction useFormValidation() {
// 封装表单数据和错误状态
const email = ref("");
const errors = ref({});

// 封装验证逻辑
const validate = () => {
    errors.value = {};
    if (!email.value) {
      errors.value.email = "此项为必填项";
    } elseif (!email.value.includes("@")) {
      errors.value.email = "请输入有效的邮箱地址";
    }
    // 如果错误对象没有属性,则验证通过
    returnObject.keys(errors.value).length === 0;
  };

// 返回响应式状态和方法
return { email, errors, validate };
}
<!-- 在组件中使用 -->
<script setup>
import useFormValidation from "./composables/useFormValidation";
// 像使用普通 Hook 一样调用,获取所需的状态和方法
const { email, errors, validate } = useFormValidation();
</script>

<template>
  <input
    v-model="email"
    @blur="validate"
  />
  <p v-if="errors.email">{{ errors.email }}</p>
</template>

为何如此: 实现 DRY、可测试、模块化的代码。这是 Vue 3 代码优化的巅峰之作
来自:https://mp.weixin.qq.com/s/ql0REKVPAl2l9yI-wNiXJA

本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!

链接: https://fly63.com/article/detial/12890

提高js加载速度,实现js无阻塞加载方式,高性能的加载执行JavaScript

为解决JS加载速度慢,采用js的延时加载,和动态加载。由于js的堵塞特性,当浏览器在加载javascript代码时,不能同时做其他任何事情,如果javascript执行时间越久,浏览器等待响应的时间就越久。

如何提高CSS性能?CSS优化、提高性能提升总汇

如何提高CSS性能,根据页面的加载性能和CSS代码性能,主要表现为: 加载性能 (主要是从减少文件体积,减少阻塞加载,提高并发方面入手),选择器性能,渲染性能,可维护性。

前端性能优化_css加载会造成哪些阻塞现象?

css的加载是不会阻塞DOM的解析,但是会阻塞DOM的渲染,会阻塞link后面js语句的执行。这是由于浏览器为了防止html页面的重复渲染而降低性能,所以浏览器只会在加载的时候去解析dom树,然后等在css加载完成之后才进行dom的渲染以及执行后面的js语句。

2018 前端性能检查表

性能十分重要。然而,我们真的知道性能瓶颈具体在哪儿吗?是执行复杂的 JavaScript,下载缓慢的 Web 字体,巨大的图片,还是卡顿的渲染?研究摇树(Tree Shaking),作用域提升(Scope Hoisting)

高性能Javascript总结

Js高性能总结:加载和运行、数据访问、DOM编程、算法和流程控制、响应接口、Ajax 异步JavaScript和XML、编程实践...

优化网站性能规则_前端性能优化策略【网络加载、页面渲染】

前端网站性能优化规则:网络加载类、页面渲染类。包括:减少 HTTP 资源请求次数、减小 HTTP 请求大小、避免页面中空的 href 和 src、合理设置 Etag 和 Last-Modified、使用可缓存的 AJAX、减少 DOM 元素数量和深度等

前端性能的本质是什么?

性能一直以来是前端开发中非常重要的话题。随着前端能做的事情越来越多,浏览器能力被无限放大和利用:从 web 游戏到复杂单页面应用,从 NodeJS 服务到 web VR/AR 和数据可视化,前端工程师总是在突破极限

BigPipe_高性能流水线页面技术

BigPipe是一个重新设计的基础动态网页服务体系。大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行。这是类似于大多数现代微处理器的流水线执行过程:多重指令管线通过不同的处理器执行单元,以达到性能的最佳。

用CSS开启硬件加速来提高网站性能

你知道我们可以在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能吗?现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。

原生js实现懒加载并节流

像淘宝网站等,页面中有着大量图片,一次性全部加载这些图片会使浏览器发送大量请求和造成浪费。采用懒加载技术,即用户浏览到哪儿,就加载该处的图片。这样节省网络资源、提升用户体验、减少服务器压力。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!