本文给大家介绍Dom节点进行优化的方案。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。
DOM操作对性能影响最大是因为它导致了浏览器的重绘和回流,我们都知道页面UI的更改都是通过DOM操作实现的,DOM虽然提供了许多api方便我们操作dom,但DOM操作的代价很高,页面前端代码的性能瓶颈也大多集中在DOM操作上,所以前端性能优化的一个主要的关注点就是DOM操作的优化。
浏览器渲染机制:
浏览器渲染页面
浏览器解析 HTML 文档的源码,然后构造出一个 DOM 树,遇到样式就异步计算。
异步计算好的样式与dom树合成,构建 render 树。
进行布局(layout) render 树。
进行绘制(painting) render 树。
DOM树与render树的区别在于:样式为display:none;的节点会在DOM树中而不在渲染树中。浏览器绘制了之后便开始解析js文件,根据js来确定是否重绘和重排。
回流·重绘
页面更改发生的操作:
- 回流:浏览器引擎发现render树某个节点发生了变化影响了布局,需要倒回去重新渲染,我们称这个回退的过程叫 回流。回流会从这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置。
- 重绘:改变某个元素的背景色、文字颜色、边框颜色等等不影响页面dom布局的操作。
js是单线程的,重绘和重排会阻塞用户的操作以及影响网页的性能
优化:减少回流重绘次数
1、改变dom多个样式,使用class,而非style,减少多次触发回流重绘
举例:改变dom元素宽高
var dom = document.getElementById('box') dom.style.width = '300px' dom.style.height = '300px'//访问了三次dom,触发了两次回流和两次重绘
优化后:
.change { width: 300px; height: 300px; } document.getElementById('p').className = 'change'//只触发一次
2、列表类型批量修改,脱离文档流再恢复,利用样式为display:none;的节点会在DOM树中而不在渲染树中不会引起重绘回流。
如果要在一个dom集合中,给每个dom子节点加一个class,我们可以遍历给每一个节点都加上class,这样就触发了多次的重绘和回流
/* //需要加入的样式 .change { width: 300px; height: 300px; } */ var ul = document.getElementsByTagName('ul') var lis = document.getElementsByTagName('li') ul.style.display = 'none' for(var i = 0; i < lis.length; i++) { lis[i].className = 'change'; } ul.style.display = 'block'
3、DocumentFragment
虚拟DOM其实就是一个对象,js提供了reateDocumentFragment()方法用于创建一个空的虚拟节点对象,DocumentFragment节点不属于文档树,当需要添加多个dom元素时,如果先将这些元素添加到DocumentFragment中,然后再将DocumentFragment对象添加到渲染树上,会减少页面渲染dom的次数,效率会明显提升。
var frag = document.createDocumentFragment() //创建一个虚拟节点对象 for(var i = 0; i < 10; i++) { var li = document.createElement("li") li.innerHTML = '我是第' + i + 1 + '个元素' frag.appendChild(li) //将li元素加到虚拟节点对象上 } ul.appendChild(frag) //将虚拟节点对象加到ul上
其它
1、事件委托,利用浏览器事件,冒泡捕获减少页面事件绑定,我们可以指定一个事件处理程序就可以管理某一类型的所有事件。事件函数过多会占用大量内存,而且绑定事件的DOM元素越多会增加访问dom的次数,对页面的交互就绪时间也会有延迟。
// 事件委托前 var lis = document.getElementsByTagName('li') for(var i = 0; i < lis.length; i++) { lis[i].onclick = function() { console.log(this.innerHTML) }} // 利用浏览器事件通过父元素委托事件给子元素 var ul = document.getElementsByTagName('ul')ul.onclick = function(event) { //也可以做判断给指定的子元素绑定事件 console.log(event.target.innerHTML)};
2、在循环中的优化减少操作dom次数
//例子1:减少在计算过程中操作dom // 优化前,访问了好多次dom,这些都是细节问题,有经验的绕过,小白平常多注意就行 for(var i = 0; i < 10; i++) { document.getElementById('el').innerHTML += '1'} // 优化后 var str = ''for(var i = 0; i < 10; i++) { str += '1'}document.getElementById('el').innerHTML = str/
这样看获取你体验不到缓存节点长度的作用,请看下面的例子
//不缓存 var ps = document.getElementsByTagName("p"), i, p; for( i=0; i<ps.length; i++ ){ p = document.createElement("p"); document.body.appendChild("p"); }造成死循环,每次执行for循环都会动态获取ps的长度,而我们每次进入循环都增加了一个DOM(p),ps的长度也+1. //缓存 var ps = document.getElementsByTagName("p"), i, p,len; for( i=0;len=ps.length;i<len; i++ ){ p = document.createElement("p"); document.body.appendChild("p"); }//使用变量保存ps的长度。
3、选择器区别
获取元素最常见的有两种方法,getElementsByXXX()和queryselectorAll(),这两种选择器区别是很大的,前者是获取动态集合,后者是获取静态集合
// 假设一开始有2个livar lis = document.getElementsByTagName('li') // 动态集合 var ul = document.getElementsByTagName('ul')[0] for(var i = 0; i < 3; i++) { console.log(lis.length) var newLi = document.createElement('li') ul.appendChild(newLi)}// 输出结果:2, 3, 4 // 优化后 var lis = document.querySelectorAll('li') // 静态集合 var ul = document.getElementsByTagName('ul')[0] for(var i = 0; i < 3; i++) { console.log(lis.length) var newLi = document.createElement('li') ul.appendChild(newLi)}// 输出结果:2, 2, 2
对静态集合的操作不会引起对文档的重新查询,相比于动态集合更加优化。
推荐学习:javascript视频教程
以上是Dom节点如何进行优化的详细内容。更多信息请关注PHP中文网其他相关文章!

是的,JavaScript的引擎核心是用C语言编写的。1)C语言提供了高效性能和底层控制,适合JavaScript引擎的开发。2)以V8引擎为例,其核心用C 编写,结合了C的效率和面向对象特性。3)JavaScript引擎的工作原理包括解析、编译和执行,C语言在这些过程中发挥关键作用。

JavaScript是现代网站的核心,因为它增强了网页的交互性和动态性。1)它允许在不刷新页面的情况下改变内容,2)通过DOMAPI操作网页,3)支持复杂的交互效果如动画和拖放,4)优化性能和最佳实践提高用户体验。

C 和JavaScript通过WebAssembly实现互操作性。1)C 代码编译成WebAssembly模块,引入到JavaScript环境中,增强计算能力。2)在游戏开发中,C 处理物理引擎和图形渲染,JavaScript负责游戏逻辑和用户界面。

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

Dreamweaver CS6
视觉化网页开发工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

SublimeText3 Linux新版
SublimeText3 Linux最新版

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)