Dom操作的性能优化

article/2025/10/19 14:24:44

        在 开发过程中,或多或少都会遇到要操作dom的情况,而dom操作多多少少都会耗费一些性能,那今天我们就一起来看看在操作dom的时候有哪些性能优化方式吧:

1.选择性能更好的获取dom元素的方法

首先,我们一起来看看,如何使用js来获取dom元素:

  • document.getElementById() / getElementsByClassName() / getElementByTagName()
  • document.querySelector() / querySelectorAll()

以上方法,都可以帮助我们获取到dom元素,但getElementXX 和 querySelectorXX 选择哪个更能节约一些性能呢?我们一起来看看吧:

首先,我们需要知道它俩获取出来的DOM集合有什么区别:

让我们一起来看一下下面这两个例子分别打印出来的结果是什么 ?

在浏览器中执行一下,会发现使用getElementsByClassName获取的DOM元素最后打印的length为2 , 使用querySelectorAll 获取的DOM元素最后打印length为1。

这是因为 getElementXX 获取的是一个HTML集合,它是一种“假定实时态”,意味着底层文档对象更新,它也会跟着更新。

而 querySelectorXX 获取的是一个NodeList集合,它不会实时返回文档结构,只会保存当前获取时的DOM结构。

因为 getElementXX 的实时更新,它的性能会比querySelector差很多,如不稍不注意还容易导致死循环 :

所以获取DOM元素尽可能使用querySelectorXX,如果必须要用getElementXX也请浅拷贝 [...boxs] 一下,来避免它的“假定实时态”。

 2.减少不必要的dom操作

我们应该都知道在浏览器实现js的操作和DOM的操作是分别独立的,js的实现名为JScript,位于jscript.dll文件中;DOM的实现存在另外一个库中,名叫mshtml.dll。

由于两者完全独立,如果两者需要沟通可以想象在他们之间建立一座“高架桥”,每次经过都需要收取“过路费”,是不是听起来就很耗费性能?所以我们应该尽可能减少经过这座“高架桥”。

尝试将DOM缓存起来:

如下图所示:第一种做法我们将经过两次“高架桥”,如果想要获取更多的属性那需要经过更多次“高架桥”。而第二种我们将DOM缓存起来,无论获取多少属性值都只需要经过一次“高架桥”。

 尽可能将更新DOM操作统一起来:

如下图所示:通过下面的两个函数 innerHTMLLoop 和 innerHTMLLoop2 执行时间来看,将需要更新的内容先缓存起来,再一次性更新到页面上效率高很多。

还有一种场景,例如我们想一次性插入1000个<li/>节点到 ul.container 中,按照常规想法我们会这样做:

如果这样做我们就像container添加了1000次,相当于经过“高架桥”1000次,我们如何通过一次来更新1000次的操作呢?

实际上是有方案的:

我们可以通过生成一个虚拟的节点对象 document.createDocumentFragement 来让1000次更新先添加到这个虚拟节点,再统一更新到container上。

还有一种方案就是:

把 .contianer{display:none;} 再向cotianer.appendClind子元素,最后通过display:block展示出来。display: none的元素不会引起页面的重排 and 重绘,也会减轻性能。 

我们可以根据自己的使用场景去选择使用方法。只要记住减少频繁的跟DOM操作即可

3.减少页面重排 and 重绘次数

上面我们提到过更新、添加页面中的DOM元素,其实只要是页面中元素发生更改,都会引发页面的重排 or 重绘。

当然浏览器也不傻,重排很耗费性能,他不会在你一需要重绘的时候就立马帮你重排 and 重绘,它会缓存一个队列定期重排 and 重绘,但有一些属性会强制页面重排 and 重绘

  • offsetTop/Left/Width/Height
  • scrollTop/Left/Width/Height
  • clientTop/Left/Width/Height

所以我们应该尽量减少这类属性的使用,如果要使用也将它缓存起来不要频繁获取。 

今天的内容就到这里结束啦,希望对大家有帮助。


http://chatgpt.dhexx.cn/article/w7HeqYwp.shtml

相关文章

常见的DOM操作有哪些

这里是修真院前端小课堂&#xff0c;本篇分析的主题是 【常见的DOM操作有哪些】 这里是修真院前端小课堂&#xff0c;每篇分享文从 【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】 八个方面深度解析前端知识/技能&…

js中Dom操作

简单的Dom获取 什么是Dom操作&#xff1f; 1.DOM使一个"使程序"和"脚本"有能力的"动态地访问"和"更新文档内容结构"&#xff0c;以及"样式"的平台和语言中立的接口. 2.在HTML和JavaScript的学习中&#xff0c;DOM操作可谓时…

TypeScript Dom操作

文章目录 介绍获取元素类型断言获取多个DOM元素操作文本内容操作样式操作事件 介绍 DOM 是浏览器提供的&#xff08;浏览器特有)&#xff0c;专门用来操作网页内容的一些JS对象(API) 通过DOM操作&#xff0c;可以让Js/Ts控制页面&#xff08;(HTML)内容&#xff0c;让页面“动…

JavaScript DOM操作

文章目录 JavaScript DOM操作DOM操作元素DOM查询修改元素内容/属性获取元素节点 DOM的增删改 DOM操作CSS内联样式获得当前正在显示的样式 DOM的事件操作事件对象事件对象的属性 事件的冒泡和事件的委托事件冒泡事件委派事件的传播事件的绑定 JavaScript DOM操作 DOM操作元素 …

DOM的操作

一、DOM的操作 1、复制节点 cloneNode(deep) 参数deep是boolean类型&#xff0c;true/false true&#xff1a;表示深度复制&#xff08;将节点及其子节点都进行复制&#xff09; --- 深拷贝 false&#xff1a;表示浅复制&#xff08;只复制节点而不复制子节点&#xff09; ----…

DOM(操作)

DOM 1 作用和分类 作用&#xff1a;使用 JS 去操作 html 和浏览器 分类&#xff1a;DOM(文档对象模型)、BOM(浏览 器对象模型) DOM 是用来呈现以及与任意HTML 或 XML文档交互的API简单说&#xff1a;DOM 是浏览器提供的一套专门用来 操作网页内容 的功能DOM的作用&am…

13前端学习之WebAPI(三):节点操作、事件高级、DOM事件流、事件委托冒泡

文章目录 一、节点操作:1. 删除节点:1.2. 案例&#xff1a;删除留言 2. 赋值(克隆)节点:3. 案例:动态生成表格:3.1 案例分析:3.2 实现: 4. 创建元素的三种方式:4.1 区别:4.2 innerTHML和createElement效率对比: 5. DOM的核心总结:5.1 创建:5.2 增加:5.3 删除:5.4 改:5.5 查&…

DOM操作

今天开始进入JS的核心操作 DOM&#xff0c;DOM操作其实很简单&#xff0c;就是增删改查这几个操作&#xff0c;先看一下思维导图&#xff1a; 1.增加操作 1.新建&#xff1a; fn creatElement(标签名) 创建元素节点 fn setAttribute&#xff08;name,value&#xff09;直接设置…

JS中DOM元素的操作

一、DOM元素的获取 1&#xff09;document.getElementsByClassName ( “class”) 返回集 htmlcollection ,用法和数组一致 说明: class为DOM元素上class属性的值 2&#xff09;document.getElementById( “id” ) 功能:返回对拥有指定ID的第一个对象的引用 返回值: DOM对象 说明…

java锁结构之无锁偏向锁轻量级锁重量级锁

一、对象的本质&#xff08;锁在对象中的体现&#xff09; 1.1、对象的结构 对象由多部分构成的&#xff0c;对象头、属性字段、补齐字段等。补齐字段是指如果对象总大小不是4字节的整数倍&#xff0c;会填充上一段内存地址是之成为4的整数倍。 其中&#xff0c;对象头在对象…

简单理解重量级锁、轻量级锁、偏向锁

全文使用synchronized来说明。 synchronized给对象上锁&#xff0c;先上偏向锁&#xff0c;在上轻量级锁&#xff0c;最后上重量级锁。上什么锁&#xff0c;是jvm根据竞争程度自行变换的。 重量级锁 计算机操作系统本有Monitor对象&#xff0c;称为管程。在java里面看不到此对…

synchronized锁升级之偏向锁

目录 一、什么是偏向锁&#xff1f; 二、偏向锁原理 三、偏向锁演示 四、偏向锁的处理流程 五、偏向锁的撤销 六、偏向锁的好处 一、什么是偏向锁&#xff1f; HotSpot作者经过研究实践发现&#xff0c;在大多数情况下&#xff0c;锁不仅不存在多线程竞争&#xff0c;而…

Java无锁、偏向锁、轻量级锁、重量级锁,锁升级过程

2. 锁 2.1 无锁 Java对象刚创建时还没有任何线程来竞争&#xff0c;说明该对象处于无锁状态&#xff08;无线程竞争它&#xff09;&#xff0c;这时偏向锁标识位是0&#xff0c;锁状态是01 。 2.2 偏向锁 偏向锁是指一段同步代码一直被同一个线程所访问&#xff0c;那么该…

偏向锁的获取和撤销详解

Java SE 1.6 为了减少获得锁和释放锁带来的性能消耗&#xff0c;引入了偏向锁和轻量级锁&#xff1b;在Java SE 1.6 中&#xff0c;锁共有4种状态&#xff0c;级别从底到高依次是&#xff1a;无锁状态、偏向锁状态、轻量级锁和重量级锁状态&#xff0c;这几种状态会随着竞争情况…

一篇文章说清 :无锁、偏向锁、轻量级锁、重量级锁

文章目录 前言一、无锁二、偏向锁三、轻量级锁&#xff08;自选锁&#xff09;四、重量级锁锁升级场景 前言 JDK1.6为了减少获得锁和释放锁所带来的性能消耗&#xff0c;引入了“偏向锁”和“轻量级锁”&#xff0c;所以在JDK1.6里锁一共有四种状态&#xff0c;无锁状态&#x…

synchronized的偏向锁、轻量级锁和重量级锁

文章目录 Java对象头偏向锁批量重偏向批量撤销 轻量级锁重量级锁Monitor 原理 Java对象头 普通对象 Mark Word在64 位虚拟机中的结构为 Mark Word后三&#xff08;两&#xff09;位表示 001&#xff1a;无锁状态101&#xff1a; 偏向锁00&#xff1a; 轻量级锁10&#xff1a…

Java synchronized偏向锁、轻量级锁、重量级锁

简介 synchronized锁共有偏向锁、轻量级锁、重量级锁三种类型&#xff0c;而这三种类型的加锁方式都是相同的&#xff0c;写代码时不用考虑加哪种锁。使用锁时对象首先会变为偏向锁状态&#xff0c;当有其它线程获取锁时会升级为轻量级锁&#xff08;没有竞争锁&#xff09;&am…

java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁

之前做过一个测试&#xff0c;详情见这篇文章《多线程 1操作的几种实现方式&#xff0c;及效率对比》&#xff0c;当时对这个测试结果很疑惑&#xff0c;反复执行过多次&#xff0c;发现结果是一样的: 1. 单线程下synchronized效率最高&#xff08;当时感觉它的效率应该是最差…

偏向锁、轻量级锁、重量级锁的区别和解析

为了换取性能&#xff0c;JVM在内置锁上做了非常多的优化&#xff0c;膨胀式的锁分配策略就是其一。理解偏向锁、轻量级锁、重量级锁的要解决的基本问题&#xff0c;几种锁的分配和膨胀过程&#xff0c;有助于编写并优化基于锁的并发程序。 内置锁的分配和膨胀过程较为复杂&…

偏向锁是什么

偏向锁操作流程偏向锁&#xff0c;顾名思义&#xff0c;它会偏向于第一个访问锁的线程&#xff0c;如果在接下来的运行过程中&#xff0c;该锁没有被其他的线程访问&#xff0c;则持有偏向锁的线程将永远不需要触发同步 但是从我们跑的代码输出却看不到偏向锁这个东东。为啥对…