11-Vue常见优化手段

news2024/11/16 21:38:31

前言:

永远不要过早优化,见招拆招

使用key

对于通过循环生成的列表,应给每个列表项一个稳定且唯一的key,这有利于在列表变动时,尽量少的删除,新增,改动元素

index作为key值是唯一的,但不够稳定,比如插入某元素,会导致后面的所有元素重新渲染,而我们想要的是只渲染新加的元素

比如有一个列表,我们需要在中间插入一个元素,在不使用 key 或者使用 index 作为 key 会发生什么变化呢?先看个图


如图的 li1 和 li2 不会重新渲染,这个没有争议的。而 li3、li4、li5 都会重新渲染
因为在不使用 key 或者列表的 index 作为 key 的时候,每个元素对应的位置关系都是 index,上图中的结果直接导致我们插入的元素到后面的全部元素,对应的位置关系都发生了变更,所以在 patch 过程中会将它们全都执行更新操作,再重新渲染。
这可不是我们想要的,我们希望的是渲染添加的那一个元素,其他四个元素不做任何变更,也就不要重新渲染
而在使用唯一 key 的情况下,每个元素对应的位置关系就是 key,来看一下使用唯一 key 值的情况下


这样如图中的 li3 和 li4 就不会重新渲染,因为元素内容没发生改变,对应的位置关系也没有发生改变。
这也是为什么 v-for 必须要写 key,而且不建议开发中使用数组的 index 作为 key 的原因

对于展示数据使用冻结对象Object.freeze()

冻结的对象不会被响应化

 当观察的对象是嵌套对象的时候,就需要递归

如果对象很多,嵌套结构很深,遍历的时间就会变长

思考:

所有的属性都需要响应式吗?

在原始数据中,有些不需要去响应式的,叫做展示数据,比如商品列表,商品价格图片这些都不能操作的

数据响应式:数据变化后,会自动重新运行依赖该数据的函数(重要)

  1. 被监控的函数

    render、computed回调、watch、watchEffect

  2. 函数运行期间用到了响应式数据(响应式数据一定是个对象)

  3. 响应式数据变化会导致函数重新运行

Vue会判断对象是否被冻结Object.isFrozen(),如果为true就不遍历

let obj = {
	a: 1,
	b: 3
}
/* 冻结对象 */
Object.freeze(obj);
obj.c = 2;
console.log(obj); // {a: 1, b: 3}

/* 判断对象是否被冻结 */
console.log(Object.isFrozen(obj));  // true

判断对象是否被冻结Object.isFrozen()

Object.isFrozen(obj);

冻结前:
在这里插入图片描述
冻结后:
在这里插入图片描述
相比于冻结前,每个属性都少了get和set方法,渲染速度更快。

使用函数式组件(无状态,无实例)

渲染函数 & JSX — Vue.js

之前创建的锚点标题组件是比较简单,没有管理任何状态,也没有监听任何传递给它的状态,也没有生命周期方法。实际上,它只是一个接受一些 prop 的函数。在这样的场景下,我们可以将组件标记为 functional,这意味它无状态 (没有响应式数据),也无实例 (没有 this 上下文)。一个函数式组件就像这样:

Vue.component('my-component', {
  functional: true,
  // Props 是可选的
  props: {
    // ...
  },
  // 为了弥补缺少的实例
  // 提供第二个参数作为上下文
  render: function (createElement, context) {
    // ...
  }
})

 

 

 

普通组件,js内存增加了30M

函数式组件,js内存增加了20M

 

 Vue不会为函数式组件创建任何一个实例

查看VNode虚拟节点,可以看到normal组件看不到函数组件

 

 使用计算属性

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

非实时绑定的表单项(v-model

当使用 v-model 绑定一个表单项时,当用户改变表单项的状态时,也会随之改变数据,从而导致 vue 发生重渲染(rerender),这会带来一些性能的开销。

特别是当用户改变表单项时,页面有一些动画正在进行中,由于JS执行线程和浏览器渲染线程是互斥的,最终会导致动画出现卡顿。

我们可以通过 v-model.lazy 或不使用 v-model 的方式解决该问题,但是注意,这样可能会导致在某一个时间段内数据和表单项是不一致的

v-model 监听 @input 事件

v-model.lazy  监听 @change 事件

保持对象引用稳定 (组件要不要重新渲染)

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

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

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

 NaN === NaN  false
NaN !== NaN  true

+0 === -0  true
1/+0   Infinity
1/-0  -Infinity

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

对于原始数据类型,保持其值不变即可

对于对象类型,保持其引用不变即可

从另一方面来说,由于可以通过保持属性引用稳定来避免子组件的重新渲染,那么我们应该细分组件来尽量避免多余的渲染

比如,做用户评论,提交最新的一条评论后,更新评论列表,有两种方法

1、添加后,重新全部从服务器拿(缺点:rerender触发频繁)

2、添加后,把新加的对象直接加到现有数据的最前面(缺点:数据不是实时的)

还是那个思想,我们只想要渲染新加的那个对象,其他的不渲染

 

 

使用v-show替代v-if

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

使用延迟装载(defer)

首页白屏时间主要受到两个因素的影响:

  • 打包体积过大

    巨型包需要消耗大量的传输时间,导致JS传输完成前页面只有一个<div>,没有可显示的内容

  • 需要立即渲染的内容太多

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

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

一个可行的方法是延迟装载组件,让组件按照指定的先后顺序依次一个一个渲染出来

本质是利用 requestAnimationFrame 事件分批渲染内容

 

 

 

 react fiber

使用keep-alive

长列表优化

打包体积优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/705993.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32外设系列—sg90(舵机)

文章目录 一、sg90简介二、引脚连接三、控制方法四、程序设计4.1 配置定时器4.2 编写控制程序 五、360舵机 一、sg90简介 首先介绍说一下什么是舵机。舵机是一种位置&#xff08;角度&#xff09;伺服的驱动器。适用于一些需要角度不断变化的&#xff0c;可以保持的控制系统。…

threejs物理效果和声音

个人博客地址: https://cxx001.gitee.io 一、Threejs中如何创建物理场景 threejs中创建物理场景我们用它的扩展库&#xff1a;Physijs。它可以使场景中的对象有重力效果&#xff0c;可以相互碰撞&#xff0c;施加力之后可以移动&#xff0c;还可以通过合页和滑块在移动过程中…

LeetCode 打卡day44--完全背包问题及其应用

一个人的朝圣 — LeetCode打卡第44天 知识总结 Leetcode 518. 零钱兑换 II题目说明代码说明 Leetcode 377. 组合总和 Ⅳ题目说明代码说明 知识总结 今天结束了完全背包问题, 完全背包问题与01背包问题的区别在于可以无限次的使用物品的数量. 其和01背包的差别在于, 01背包先遍…

Leetcode-每日一题【707. 设计链表】

题目 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需要属性 prev 以指示链表中的上一…

Spring Boot 中的 @Id 注解是什么,原理,如何使用

Spring Boot 中的 Id 注解是什么&#xff0c;原理&#xff0c;如何使用 在 Spring Boot 中&#xff0c;Id 注解是一个非常重要的注解&#xff0c;它用于映射实体类中的主键字段。本文将介绍 Id 注解的作用、原理和使用方法。 1. Id 注解的作用 在 Spring Boot 中&#xff0c;…

shardingsphere-proxy 实现postgresql的分库分表

1、docker 安装zookeeper 1、拉取镜像 docker pull zookeeper2、运行容器 docker run -d -e TZ"Asia/Shanghai" -p 2181:2181 -v /home/sunyuhua/docker/zookeeper:/data --name zookeeper --restart always zookeeper3、查看容器是不是运行成功 docker exec -i…

threejs场景

个人博客地址: https://cxx001.gitee.io 前言 对象添加到场景里才能被渲染&#xff0c;场景是整个画面的容器。场景要显示任何东西&#xff0c;一般要有摄像机、光源、渲染对象。本章主要介绍场景类里常用的方法和属性&#xff0c;以及构建场景的基本组件。几何体和网格&…

从小白开始学习CAD(一)

什么是CAD ? CAD是计算机辅助设计&#xff08;Computer-Aided Design&#xff09;的缩写&#xff0c;它是一种利用计算机软件辅助进行设计和绘图的技术。 CAD是干什么的&#xff1f; CAD广泛应用于工程设计、建筑设计、产品设计等领域&#xff0c;可以提高设计效率、减少错误…

EthersV6之BigInt踩坑记录

起因&#xff1a;今天在调用合约的时候发现使用 BIgInt 丢了精度。看了下发现是自己的姿势不对&#xff0c;记录一下问题。 一、错误操作 const amountIn 2e24 const contract contract.function(BigInt(Number(2e24))为什么会这么写呢&#xff0c; 因为我们前端库升级到了 …

【C语言初阶(6)】猜数字游戏

文章目录 1. 游戏描述2. 代码结构2.1 菜单函数2.2 游戏函数2.3 主体函数 3. 代码实现 1. 游戏描述 电脑自动生成一个1-100以内的数字。我们输入一个我们猜的数字。如果我们猜的数字比电脑随机生成的数字大&#xff0c;那么输出&#xff08;猜大了&#xff09;&#xff0c;反之…

【MinIO异常】Storage reached its minimum free drive threshold 的解决方案

Storage reached its minimum free drive threshold 的解决方案 一、背景描述二、原因分析三、问题解决 一、背景描述 部署在Linux服务器上的MinIO服务器昨天使用的还正常&#xff0c;包含上传文件&#xff0c;下载文件&#xff0c;登录MinIO浏览器端&#xff0c;然而今天登录…

chatgpt赋能python:同一个python文件能同时运行多次吗?

同一个python文件能同时运行多次吗&#xff1f; Python作为一种高级编程语言&#xff0c;具有丰富的语法和功能。在编写Python程序时&#xff0c;我们常常需要考虑不同的需求。有时我们可能需要使用相同的python文件运行不同的程序&#xff0c;这时候很自然的问题就会出现&…

【机器学习】【期末复习】有关机器学习的简答题可供期末复习参考

本文为学校课程《机器学习》中老师给出的一些有关机器学习的简答题的详细解答&#xff0c;可供复习参考&#xff0c;基本答案全是正确的。 目录 什么是判别式模型和生成式模型&#xff0c;并且举例说明各自包含哪些典型的机器学习模型&#xff1f;L1 和 L2 的正则化的区别数据归…

Node.js 包管理器(Corepack)

目录 1、简介 2、启用Corepack 3、使用Node.js Corepack 4、配置包 5、升级全局版本 6、离线工作流 7、支持的包管理器 8、Node.js Corepack 拦截npm 9、Corepack 常用命令 1、简介 Corepack是一个实验性的工具&#xff0c;可以帮助管理包管理器的版本。它公开的二进制…

C#,数值计算——循环冗余校验和(CRC,Cyclic Redundancy Checksum)的计算方法与源代码

using System; namespace Legalsoft.Truffer { /// <summary> /// 循环冗余校验和 /// cyclic redundancy checksum /// </summary> public class Icrc { private uint jcrc { get; set; } private uint jfill { get; se…

【ISO26262】汽车功能安全第3部分:概念阶段

GB/T34590《道路车辆 功能安全》分为以下部分: 需要文档的朋友,可以和我联系! tommi_wei@163.com GB/T34590的本部分规定了车辆在概念阶段的要求: ———相关项定义; ———安全生命周期启动; ———危害分析和风险评估;及 ———功能安全概念。 危害事件分类 对于每一个…

多网口UDP发包无法收到回包排查与解决

最近几周几乎都是单休&#xff0c;加班很多&#xff0c;也遇到了很多未知的问题&#xff0c;杂事也多时间比较紧张&#xff0c;也没有多少空余来进行一些总结积累。这点让我很是怀念起几年前的日子&#xff0c;任务安排周期长&#xff0c;做技术纯粹又专心。 前几天遇到了一个…

chatgpt赋能python:如何将Python导入PyCharm

如何将Python导入PyCharm 介绍 PyCharm是一个非常流行的Python开发工具&#xff0c;它拥有许多强大的功能和插件&#xff0c;使开发人员能够更高效地编写Python代码。在本篇文章中&#xff0c;我们将介绍如何将Python导入PyCharm。 步骤 1. 安装PyCharm 首先&#xff0c;您…

jupyter-notebook:从记录点回复数据

使用jupyter进行记录数据分析思路时&#xff0c;有时候会莫名出现一些问题。比如这次遇到的保存并关闭之后&#xff0c;隔了一个晚上再次打开文件就成了空文件了&#xff0c;昨天写的分析都没有了&#xff0c;很头疼。解决方法&#xff1a;如果确定是保存了后&#xff0c;每一个…

32 linux 中物理页的 cow

前言 熟悉 linux 进程机制的人都知道 linux 中新建进程是以 fork exec 的形式创建的进程 fork 的时候复制了父进程的相关数据结构, 然后更新了待执行的 binary, 去执行 然后 父子进程之间 内存管理是 基于 copy on write 的 对于某块物理页, fork 之后内存设置为 只读…