vue - 常见的性能优化

文章目录
- vue使用中常见的性能优化
- 1, v-for 遍历避免同时使用 v-if
- 2, 如果需要使用v-for给每项元素绑定事件时 可以使用事件代理**
- 3, 一些数据不做响应式
- 4,一些页面采用`keep-alive`缓存组件
- 5,第三方UI库按需导入
- 6,列表数据的懒加载 上滑加载分页数据
- 7,变量本地化
- 8,事件的销毁
vue使用中常见的性能优化
1, v-for 遍历避免同时使用 v-if
在 Vue2 中 v-for 优先级更高,所以编译过程中会把列表元素全部遍历生成虚拟 DOM,再来通过 v-if 判断符合条件的才渲染,就会有多余的逻辑判断和造成性能的浪费,因为我们希望的是不符合条件的虚拟 DOM都不要生成;
1,为了过滤一个列表中的项目 (比如 v-for="user in users" v-if="user.isActive")。在这种情形下,可以将 users 替换为一个计算属性或者方法 (比如 activeUsers),让其返回过滤后的列表;
<ul><liv-for="user in activeUsers":key="user.id">{{ user.name }}</li>
</ul>methods:{// 方法activeUsers(){//在这里面处理需要显示的数据 然后返回筛选过的列表}
}
2,为了避免渲染本应该被隐藏的列表 (比如 v-for="user in users" v-if="shouldShowUsers")。这种情形下,请将 v-if 移动至容器元素上 (比如 ul、ol)。
<ul v-if="shouldShowUsers"><liv-for="user in users":key="user.id">{{ user.name }}</li>
</ul>
在 Vue3 中 v-if 的优先级更高,就意味着当判断条件是 v-for 遍历的列表中的属性的话,v-if 是拿不到的;
注意:永远不要把 v-if 和 v-for 同时用在同一个元素上。
2, 如果需要使用v-for给每项元素绑定事件时 可以使用事件代理**
事件代理的本质就是利用事件冒泡到父元素的特性。这样就可以不用在循环的节点上每一个都加事件了;如下:
在父元素ul上面添加点击事件,如过需要传参的话 只需要添加自定义属性即可,比如下面的 id属性
<!-- 使用事件委托进行处理和传参 添加自定义属性id --><ul class="weekdays" @click="debounce($event)"><li v-for="(item, index) in dayList" :key="index" :id="index" >{{ item.day }}</li></ul>
// 事件委托处理debounce(event) {if (event.target && event.target.nodeName == "LI") {// 现在就可以拿到当前的节点 所以就能拿到里面的属性和数据console.log("我点击的是:", event.target);}},
事件代理好处有2 个
1,将事件处理程序代理到父节点,减少内存占用率;
2,动态生成子节点时能自动绑定事件处理程序到父节点;
3, 一些数据不做响应式
一些数据不做响应式 比如会员列表、商品列表之类的,只是纯粹的数据展示,不会有任何动态改变的场景下,就不需要对数据做响应化处理,可以大大提升渲染速度;
可以使用 Object.freeze() 方法冻结一个对象,该方法冻结的对象不能被修改;即不能向这个对象添加新属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值,以及该对象的原型也不能被修改;
export default {data: () => ({userList: []}),async created() {const users = await axios.get("/api/users");this.userList = Object.freeze(users);}
};
Vue2 的响应式源码地址:src/core/observer/index.js - 144行 是这样的:
export function defineReactive (...){// getOwnPropertyDescriptor 返回指定对象上一个自有属性对应的属性描述符// 也就是直接赋予该对象的属性,不需要从原型链上进行查找的属性const property = Object.getOwnPropertyDescriptor(obj, key)判断configurable` 为 `false`不做处理if (property && property.configurable === false) {return}...
}
可以看到一开始就判断 configurable 为 false 的直接返回不做响应式处理;
configurable` 为 `false` 表示这个属性是不能被修改的,而冻结的对象的 `configurable` 就是为 `false
这是vue正常定义在data里面的数据,会自动把下面的所有属性都添加get和set属性,有多少就添加多少:

开始冻结对象:
freList是请求后端的列表数据;
created() {this.dayList = Object.freeze(freList)console.log("daylist:",this.dayList);},
可以看出已经没有get和set属性了,但同时这些数据也不具备响应式了;

4,一些页面采用keep-alive缓存组件
比如在表单输入页面进入下一步后,再返回上一步到表单页时要保留表单输入的内容、比如在列表页>详情页>列表页,这样来回跳转的场景等;
基础使用:
如果需要缓存整个项目,则如下设置(直接包裹根router-view即可):<keep-alive><router-view> </router-view></keep-alive>缓存部分页面或者组件,使用route.meta属性<keep-alive><router-view v-if="$route.meta.keepAlive"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive"></router-view>注:<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。<keep-alive><component :is="view"></component></keep-alive>
注意: 配置了keepAlive的页面,在再次进入时不会重新渲染(第一次进来时会触发所有钩子函数),该页面内的组件同理不会再次渲染。
而这可能会导致该组件内的相关操作(那些每次都需要重新渲染页面的操作:如父子组件间的传值)不再生效。 这一点可能会导致一些莫名其妙而又无从查证的bug;
vue2.1.0 新增了include,exclude俩个属性,允许组件有条件的缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示。
<!-- 逗号分隔字符串 --><keep-alive include="a,b"><component :is="view"></component></keep-alive><!-- 正则表达式 (需要 `v-bind`绑定) --><keep-alive :include="/a|b/"><component :is="view"></component></keep-alive><!-- 数组 (需要 `v-bind`绑定) --><keep-alive :include="['a', 'b']"><component :is="view"></component></keep-alive>
注:匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。
动态判断,使用v-bind:include
<keep-alive :include="includedComponents"><router-view></router-view>
</keep-alive>includedComponents动态设置即可
使用beforeRouteLeave或者afterEach中进行拦截处理
如在项目在Category组件中的设置:
beforeRouteLeave(to,from,next){if(to.name=='DemoIndex'){if(!from.meta.keepAlive){from.meta.keepAlive=true}next()}else{from.meta.keepAlive=falseto.meta.keepAlive=falsenext()}
},
在beforeRouteLeave中to.name根据具体的路由进行动态缓存设置
使用keepAlive后生命周期变化(重要):
首次进入缓存页面:beforeRouteEnter --> created --> mounted --> activated --> deactivated
再次进入缓存页面:beforeRouteEnter --> activated --> deactivated
注:
1、这里的activated非常有用,因为页面被缓存时,created,mounted等生命周期均失效,你若想进行一些操作,那么可以在activated内完成(下面会举个栗子:列表页回到上次浏览位置)
2、activated keep-alive组件激活时调用,该钩子在服务器端渲染期间不被调用。
3、deactivated keep-alive组件停用时调用,该钩子在服务端渲染期间不被调用。
5,第三方UI库按需导入
比如 vantUi, element-ui库的按需引入;见这篇文章
6,列表数据的懒加载 上滑加载分页数据
列表数据的懒加载滚动条上划到底时开始请求下一页的数据,尽量配合防抖函数使用,防止一瞬间请求的次数太多。
如下代码:
这边我用的是vue3写的,vue2只是获取节点的方式不一样,其他都一样的;
onMounted(() => {// 获取滚动容器的节点let containerEle = showContentEl.value;if (!containerEle) return;// 监听滚动条containerEle.addEventListener("scroll", function () {const clientHeight = containerEle.clientHeight;const scrollTop = parseInt(containerEle.scrollTop);const scrollHeight = containerEle.scrollHeight;// 判断是否滚动条是否滚动到底 (-1是为了控制误差)if (clientHeight + scrollTop >= scrollHeight - 1) {// 开始防抖请求数据debounceLoadMaterialList();}});
});<template><div class="container"><div class="list">展示的列表数据</div></div>
</template>
设置接口防抖:
import * as _ from "lodash";
// 设置接口防抖
const debounceLoadMaterialList = _.debounce(loadMaterialList, 500);
7,变量本地化
简单说就是把会多次引用的变量保存起来,因为每次访问 this.xx 的时候,由于是响应式对象,所以每次都会触发 getter,然后执行依赖收集的相关代码,如果使用变量次数越多,性能自然就越差;
从需求上说在一个函数里一个变量执行一次依赖收集就够了,可是很多人习惯性的在项目中大量写 this.xx,而忽略了 this.xx 背后做的事,就会导致性能问题了;
比如下面vue2的例子:
<template><div :style="{ opacity: number / 100 }"> {{ result }}</div>
</template>
<script>
import { someThing } from '@/utils'
export default {props: ['number'],computed: {base () { return 100 },result () {let base = this.base, number = this.number // 保存起来 -- 变量本地化for (let i = 0; i < 1000; i++) {number += someThing(base) // 避免频繁引用 this.xx}return number}}
}
</script>
8,事件的销毁
Vue 组件销毁时,会自动解绑它的全部指令及事件监听器,但是仅限于组件本身的事件;
而对于定时器、 addEventListener 注册的监听器等,就需要在组件销毁的生命周期钩子中手动销毁或解绑,以避免内存泄露;
<script>
export default {created() {this.timer = setInterval(this.refresh, 2000)addEventListener('touchmove', this.touchmove, false)},beforeDestroy() {clearInterval(this.timer)this.timer = nullremoveEventListener('touchmove', this.touchmove, false)}
}
</script>
相关文章:
vue - 常见的性能优化
文章目录 vue使用中常见的性能优化1, v-for 遍历避免同时使用 v-if2, 如果需要使用v-for给每项元素绑定事件时 可以使用事件代理**3, 一些数据不做响应式4,一些页面采用keep-alive缓存组件5,第三方UI库按需导入6&#…...
微服务系列文章 之 Nginx服务状态监控的方法
在Nginx的插件模块中有一个模块stub_status可以监控Nginx的一些状态信息,默认安装可能没有这个模块,手动编译的时候加一下即可。 1. 模块安装 先使用命令查看是否已经安装这个模块: [rootihxb123Z nginx]# ./nginx -V (V大写会显示版本号和…...
【网络系统集成】路由器实验
1.实验名称:路由器RIP协议配置 2.实验目的 在PacketTracer中进行模拟实验,配置RIP协议,验证RIP协议更新时间及路由状态变化,加深对路由器RIP协议相关知识的理解与掌握。 3.实验内容 (1)拓扑结构图 (2)ip地址分配与端口分配...
【mac 安装Miniconda】
1.下载Miniconda 注意mac是什么版本,m1下载m1版本 https://docs.conda.io/en/latest/miniconda.html#macos-installers 2.安装Miniconda 在下载文件所在目录下打开终端,输入一下命令: bash Miniconda3-latest-MacOSX-x86_64.sh 一路回车&…...
螺栓疲劳计算-风电行业,参考GL2010, ST0361,1993-1-9
由于不想再重新排版了,于是转成了图片。...
QT学习之旅 - QThread多线程
文章目录 首先是主线程 其次是一个程序 通过一个QThread来放入程序 进阶一点: 手动开启关闭线程俩个线程 其实QT中的thread(线程)是很容易的 首先是主线程 #include "mainwindow.h" #include "ui_mainwindow.h"#include <QDebug>MainWindow::MainWin…...
PROFINET转TCP/IP网关TCP/IP协议的含义是
大家好,今天要和大家分享一款自主研发的通讯网关,远创智控YC-PN-TCPIP。这款网关可是集多种功能于一身,PROFINET从站功能,让它在通讯领域独领风骚。想知道这款网关如何实现PROFINET和TCP/IP网络的连接吗?一起来看看吧&…...
计算机网络基础第六章
一、应用层概述 1.1 网络应用模型 1.1.1 客户/服务器(C/S)模型 1.1.2 P2P模型 二、域名解析系统——DNS系统 2.1 域名 2.2 域名服务器 2.3 域名解析过程 三、文件传输协议——FTP 3.1 FTP服务器和用户端 3.2 FTP工作原理 四、电子邮件 4.1 电子邮件系统概述 4.2 简单邮件传送…...
MobPush:Android客户端SDK厂商通道回执配置指南
华为厂商回执配置 登录华为AppGallery Connect网站。在左侧菜单点击增长 - 推送服务,进入推送服务页面后,点击配置页签,检查应用回执状态,如未开通请点击右侧开通按钮。 如已开通,点击修改按钮,弹出“选择…...
Karmada: Open, Multi-Cloud, Multi-Cluster Kubernetes Orchestration
Karmada是一个开源的多云应用编排和管理平台,旨在帮助用户在多个云提供商之间无缝地部署、编排和管理应用程序。 Karmada(Kubernetes Armada)是一个Kubernetes管理系统,它使您能够在多个Kubernetes集群和云环境中运行云原生应用程…...
arcgis拓扑检查
不能有悬挂点 不能有伪结点***路网处理很重要,看研究吧。 一直默认到最后。 导入要素类,单个 toupu2右键新建拓扑(T) 一般选不能有悬挂点,不能重叠。 一路默认 是 拉进图层可视化 线要素的话记得添加字段length&#…...
icp许可证 办理流程(icp资质申请条件)
icp许可证 办理流程(icp资质申请条件)是什么? ICP经营许可证是可以线上无忧办理的,包下证,流程也很简单,只需要你提供企业营业执照、法人身份证这些基础材料就可以。加急10-20工作日拿证,普通20-60工作日拿证。 在了解…...
三菱PLC 控制灯一秒钟交替闪烁
三菱PLC中常用的特殊继电器: M8000 上电一直ON标志 M8002 上电导通一次 M8004 PLC出错 M8005 PLC备用电池电量低标志 M8011 10ms时钟脉冲 M8012 100ms时钟脉冲 M8013 1s时钟脉冲 M8014 1min时钟脉冲 M8034…...
金融数据库的战场,太平洋保险和OceanBase打了场胜仗
点击关注 文丨刘雨琦 “数据库的国产替代,必须经过严格的考虑,保证不会出错,所以大多数企业的领导层选择按兵不动或者简单扩容。因为不换就不会错,选了很久如果选错,还可能会出现重大事故。” 某银行数据库技术人员…...
IP协议【图解TCP/IP(笔记九)】
文章目录 IP即网际协议IP相当于OSI参考模型的第3层网络层与数据链路层的关系 IP基础知识IP地址属于网络层地址路由控制■ 发送数据至最终目标地址■ 路由控制表 数据链路的抽象化IP属于面向无连接型 IP即网际协议 TCP/IP的心脏是互联网层。这一层主要由IP(Internet…...
C#仿热血江湖
目录 1 定义属性 2 GClass86_0 3 Int32 4 List 5 NpcID 定义属性 private int _NpcID; private GClass86 gclass86_0 = new GClass86(); private int int_0;...
Nginx静态资源部署
要在 Nginx 上部署静态资源,可以按照以下步骤进行操作: 确保已经安装并配置好 Nginx。如果还没有安装,可以参考 Nginx 的官方文档进行安装和配置。 将静态资源文件复制到 Nginx 的默认静态文件目录下。默认情况下,Nginx 的静态文…...
javaee jstl表达式
jstl是el表达式的扩展 使用jstl需要添加jar包 package com.test.servlet;import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;import javax.servlet.ServletException; import javax.servlet…...
ChatGPT是否具有记忆能力?
ChatGPT在某种程度上具有记忆能力,但它的记忆能力有限且不像人类的记忆那样全面和持久。以下是对ChatGPT的记忆能力的详细分析: 1. 上下文记忆:ChatGPT可以在对话过程中记住先前的对话历史,以便更好地理解和回应后续的问题。通过…...
ARP协议(地址分析协议)
系列文章目录 数通王国历险记(4) 目录 前言 一,什么是地址解析协议(ARP) 二,封装和解封装 三,为什么需要地址解析协议(ARP) 四,ARP的验证实验 4.1&#x…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
