【JavaScript】减少 DOM 操作

文章目录

    • 1. 了解DOM操作的性能影响
    • 2. 批量操作和缓存选择器
      • 2.1 批量操作
      • 2.2 缓存选择器
    • 3. 使用事件委托
    • 4. 缓存计算值
    • 5. 合理使用样式操作
    • 6. 使用文档碎片和克隆节点
    • 7. 总结

在Web开发中,对DOM(Document Object Model)的频繁操作可能导致性能问题。DOM操作涉及到页面的重绘和重排,而这些过程是相对昂贵的。因此,优化DOM操作是提高网页性能的关键。本篇博客将分享一些减少DOM操作的技巧,帮助你更高效地编写JavaScript代码。

1. 了解DOM操作的性能影响

在进行DOM操作之前,首先要了解它们可能对性能产生的影响。DOM的每次操作都可能引发浏览器的重排和重绘,这意味着整个页面的布局和渲染都会受到影响。频繁的DOM操作可能导致页面的性能下降,用户体验变差。

2. 批量操作和缓存选择器

2.1 批量操作

将多个DOM操作合并为一个批量操作,以减少重排的次数。可以使用文档片段(DocumentFragment)来进行批量操作。文档片段是一个虚拟的节点容器,可以在其中执行DOM操作,然后一次性将其添加到文档中。

// 不推荐的写法,会引发多次重排
for (let i = 0; i < 100; i++) {document.getElementById('container').innerHTML += '<div>' + i + '</div>';
}// 推荐的写法,使用文档片段进行批量操作
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {const div = document.createElement('div');div.textContent = i;fragment.appendChild(div);
}
document.getElementById('container').appendChild(fragment);

2.2 缓存选择器

避免在循环中重复使用昂贵的DOM选择器,将选择器的结果缓存起来以提高性能。

// 不推荐的写法,每次循环都重新查询DOM
for (let i = 0; i < 100; i++) {document.querySelector('.element').style.color = 'red';
}// 推荐的写法,缓存选择器的结果
const element = document.querySelector('.element');
for (let i = 0; i < 100; i++) {element.style.color = 'red';
}

3. 使用事件委托

事件委托是一种在父元素上监听事件,通过事件对象的target属性判断目标元素的技术。它可以减少事件处理器的数量,降低内存占用,也能减少DOM操作。

<!-- 不推荐的写法,为每个按钮添加事件处理器 -->
<button id="button1">Button 1</button>
<button id="button2">Button 2</button>
<button id="button3">Button 3</button><script>document.getElementById('button1').addEventListener('click', () => {console.log('Button 1 clicked');});document.getElementById('button2').addEventListener('click', () => {console.log('Button 2 clicked');});document.getElementById('button3').addEventListener('click', () => {console.log('Button 3 clicked');});
</script>
htmlCopy code<!-- 推荐的写法,使用事件委托 -->
<div id="buttons-container"><button id="button1">Button 1</button><button id="button2">Button 2</button><button id="button3">Button 3</button>
</div><script>document.getElementById('buttons-container').addEventListener('click', (event) => {if (event.target.tagName === 'BUTTON') {console.log(`${event.target.textContent} clicked`);}});
</script>

4. 缓存计算值

在进行多次DOM操作时,避免在每次操作前都查询DOM元素的计算值。将计算值缓存起来,以减少浏览器的计算开销。

// 不推荐的写法,每次操作前都重新查询计算值
const width = document.getElementById('element').offsetWidth;
document.getElementById('element').style.width = (width + 10) + 'px';// 推荐的写法,缓存计算值
const element = document.getElementById('element');
const width = element.offsetWidth;
element.style.width = (width + 10) + 'px';

5. 合理使用样式操作

避免在循环中频繁进行样式操作,尽量通过添加或移除类名的方式进行样式变更。样式的变更会引起重排和重绘,通过添加或移除类名可以将多个样式变更合并为一次重排和重绘。

// 不推荐的写法,每次循环都进行样式变更
for (let i = 0; i < 100; i++) {document.getElementById('element').style.fontSize = i + 'px';
}// 推荐的写法,通过添加或移除类名进行样式变更
for (let i = 0; i < 100; i++) {document.getElementById('element').classList.add('font-size-' + i);
}

6. 使用文档碎片和克隆节点

当需要重复插入相似的DOM结构时,可以考虑使用文档碎片或克隆节点的方式,减少重排次数。

// 不推荐的写法,每次循环都插入新的元素
for (let i = 0; i < 100; i++) {const div = document.createElement('div');document.getElementById('container').appendChild(div);
}// 推荐的写法,使用文档碎片或克隆节点
const fragment = document.createDocumentFragment();
const template = document.getElementById('template');for (let i = 0; i < 100; i++) {// 使用文档碎片const div = document.createElement('div');fragment.appendChild(div);// 或使用克隆节点// const div = template.cloneNode(true);// fragment.appendChild(div);
}document.getElementById('container').appendChild(fragment);

7. 总结

减少DOM操作是提高Web应用性能的有效途径之一。通过使用文档片段、事件委托、缓存选择器、缓存计算值等技巧,可以有效降低浏览器的重排和重绘次数,提高页面性能。在编写JavaScript代码时,要时刻关注DOM操作的影响,并选择最优的方案。希望通过本篇博客,你对如何减少DOM操作有了更清晰的认识,并能够在实际项目中应用这些技巧。

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

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

相关文章

C++面试题精选与解析

C面试题精选与解析 一、基础与语法 请问C中的指针和引用有什么区别&#xff1f; 指针是一个变量&#xff0c;存储的是另一个变量的内存地址。指针可以被重新赋值以指向另一个不同的对象。而引用是某个变量的别名&#xff0c;一旦引用被初始化为一个变量&#xff0c;就不能改变…

LLM权重量化

LLM权重量化 浮点表示的背景知识Nave 8位量化使用LLM.int8() 进行8位量化结论References 大型语言模型(llm)以其广泛的计算需求而闻名。通常&#xff0c;模型的大小是通过将**参数的数量(大小)乘以这些值的精度(数据类型)**来计算的。为了节省内存&#xff0c;可以通过称为量化…

cmake 项目。qt5升级 qt6 报错 error: “Qt requires a C++17 compiler 已解决

日常项目开发中。需要对qt5升级到qt6 做cmake兼容配置&#xff0c;在编译中发现&#xff0c;有c 编译环境 报错 2>C:\Qt\6.5.3\msvc2019_64\include\QtCore/qcompilerdetection.h(1226,1): fatal error C1189: #error: "Qt requires a C17 compiler, and a suitable …

了解 JavaScript 中的重放攻击和复现攻击

在网络安全领域&#xff0c;重放攻击&#xff08;Replay Attack&#xff09;和复现攻击&#xff08;Playback Attack&#xff09;是一些可能导致安全漏洞的攻击形式。这两种攻击类型涉及在通信过程中再次发送已经捕获的数据&#xff0c;以达到欺骗系统的目的。本文将介绍 JavaS…

企业微信怎么变更企业名称?

企业微信变更主体有什么作用&#xff1f;现在很多公司都用企业微信来加客户&#xff0c;有时候辛辛苦苦积累了很多客户&#xff0c;但是公司却因为各种各样的原因需要注销&#xff0c;那么就需要通过企业微信变更主体的方法&#xff0c;把企业微信绑定的公司更改为最新的。企业…

Qt Android sdk配置报错解决

使用的jdk8总是失败&#xff0c;报错command tools run以及platform sdk等问题。后来主要是设置jdk版本为17&#xff0c;就配置生效了。Android sdk路径可以选用Android Studio自带的&#xff0c;但是也要在Qt中点击“设置SDK”按钮做必要的下载更新等。 编译器这里会自动检测到…

linux中的权限

Linux 的权限 在了解Linux的权限之前&#xff0c;我们需要知道Linux的构成&#xff0c;Linux分为三个部分&#xff0c;内核、外部程序、以及用户。 内核&#xff1a; 内核一般是指Linux的操作系统&#xff0c;用来执行用户发送的指令 或者 拒绝执行用户发布指令时而发出的报…

大数据之Flink优化

文章目录 导言&#xff1a;Flink调优概览第1章 资源配置调优1.1 内存设置1.1.1 TaskManager 内存模型1.1.2 生产资源配置示例 1.2 合理利用 cpu 资源1.2.1 使用 DefaultResourceCalculator 策略1.2.2 使用 DominantResourceCalculator 策略1.2.3 使用DominantResourceCalculato…

YOLOv9来了,可编程梯度信息与广义高效层聚合网络 助力全新检测SOTA前沿

本文首发&#xff1a;AIWalker 欢迎关注AIWalker&#xff0c;近距离接触底层视觉与基础AI技术 摘要 当今的深度学习方法侧重于如何设计最合适的目标函数&#xff0c;以便模型的预测结果最接近真实情况&#xff1b;与此同时&#xff0c;必须设计一个适当的架构&#xff0c;以便…

[electron]官方示例解析

官方例子 github链接 main.js const { app, BrowserWindow } require(electron)说句实话这里的语法是有部分看不懂的。导入模块虽然electron有很多模块。但是这里只是用到了app 和 BrowserWindow function createWindow () {// Create the browser window.const mainWindo…

解锁网络世界的大门:探索Gateway网关的奇妙之旅(二)

本系列文章简介&#xff1a; 本系列文章将带领您深入探索Gateway网关的神秘世界。我们将了解它们的工作原理、功能和重要性&#xff0c;以及它们在互联网中的角色。您将会发现&#xff0c;这些看似普通的设备&#xff0c;实际上拥有着惊人的能力和影响力。我们将揭示它们背后隐…

go语言的理解,看这一篇就够了

1.来源 Go语言是谷歌2009年发布的第二款开源编程语言 2.谷歌为什么要创建Go语言 计算机硬件技术更新频繁, 性能提高很快,默目前主流的编程语言发展明显落后于硬件,不能合理利用多核多CPU的优势提升软件系统性能软件系统复杂度越来越高,维护成本越来越高,目前缺乏一个简洁而高效…

SSM项目集成Spring Security 4.X版本 之 加入DWZ,J-UI框架实现登录和主页菜单显示

目录 前言 一、加入DWZ J-UI框架 二、实现登录页面 三、实现主页面菜单显示 前言 大家好&#xff01;写文章之前先列出几篇相关文章。本文内容也在其项目中接续实现。 一. SSM项目集成Spring Security 4.X版本&#xff08;使用spring-security.xml 配置文件方式&#xff…

eclipse中open Type 、 open type in Hierachy、open Resource的区别

目录 场景&#xff1a; open Type open Resource open type in Hierachy 场景&#xff1a; 在项目中想要研究底层代码&#xff0c;经常要用eclipse看依赖jar包的类&#xff0c;比如spring的源码中AbstractApplicationContext类CTLSHIFTT用的少&#xff0c;经常用的CTLSHIR…

YOLO系列论文阅读(v1--v3)

搞目标检测&#xff0c;绕不开的一个框架就是yolo&#xff0c;而且更糟糕的是&#xff0c;随着yolo的发展迭代&#xff0c;yolo网络可以做的事越来越多&#xff0c;语义分割&#xff0c;关键点检测&#xff0c;3D目标检测。。。这几天决定把YOLO系列彻底梳理一下&#xff0c;在…

leet hot 100-4 移动零

移动零 原题链接思路代码 原题链接 leet hot 100-4 283. 移动零 思路 遍历数组 将非0数字 移动到数组前端 数字0就会被移动到数组末端 时间复杂度O(n) 空间复杂度(n) 代码 class Solution { public:void moveZeroes(vector<int>& nums) {int start 0;int ind…

Spring篇----第五篇

系列文章目录 文章目录 系列文章目录前言一、Spring IoC 的实现机制。二、什么是 spring bean?三、spring 提供了哪些配置方式?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享…

CNCF之毕业Projects简介

CNCF组织管理着大量的云原生基础设施软件系统&#xff0c;如著名的k8s&#xff0c;不同的系统解决不同的技术点&#xff0c;也有一些系统是解决同一个问题的&#xff0c;形成一个自由竞争的关系&#xff0c;互相促进彼此创新进步&#xff0c;同时也给我们做技术选型带来了多样性…

XSS原理和攻防

Cross Site Scripting:跨站脚本攻击 用户提交的数据中可以构造恶意代码&#xff0c;并且执行&#xff0c;从而实现窃取用户信息等攻击 攻击&#xff1a; 防御&#xff1a; 1.对输入进行过滤&#xff0c;对输出进行编码 2.cookie设置http-only

Android 如何添加自定义字体

Android 如何添加自定义字体 比如我要添加 jetbrains 相关字体 在 res 文件夹中添加 font 文件夹。里面放入你的字体文件 .ttf .otf&#xff0c;字体文件名需要是小写&#xff0c;只能是字母和下划线。 在 xml 布局文件中直接通过 android:fontFamily"font/jetbrainsmo…