小编给大家分享一下Dom节点怎么进行优化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!
Dom操作对性能影响最大是因为它导致了浏览器的重绘和回流,我们都知道页面UI的更改都是通过Dom操作实现的,Dom虽然提供了许多api方便我们操作Dom,但Dom操作的代价很高,页面前端代码的性能瓶颈也大多集中在Dom操作上,所以前端性能优化的一个主要的关注点就是Dom操作的优化。
浏览器渲染机制:
- <李>
浏览器解析HTML文档的源码,然后构造出一个Dom树,遇到样式就异步计算。
李> <李>异步计算好的样式与Dom树合成,构建渲染树。
李> <李>进行布局(布局)渲染树。
李> <李>进行绘制(绘画)渲染树。
李>Dom树与渲染树的区别在于:样式为显示:没有;的节点会在Dom树中而不在渲染树中。浏览器绘制了之后便开始解析js文件,根据js来确定是否重绘和重排。
回流·重绘
页面更改发生的操作:
- <李>
回流:浏览器引擎发现渲染树某个节点发生了变化影响了布的局,需要倒回去重新渲染,我们称这个回退的过程叫回流。回流会从这个根框架开始递归往下,依次计算所有的结点几何尺寸和位置。
李> <李>重绘:改变某个元素的背景色,文字颜色,边框颜色等等不影响页面Dom布局的操作。
李>js是单线程的,重绘和重排会阻塞用户的操作以及影响网页的性能
优化:减少回流重绘次数
1,改变Dom多个样式,使用类,而非风格,减少多次触发回流重绘
举例:改变Dom元素宽高
var dom =, . getelementbyid(& # 39;盒# 39;) 时间=dom.style.width & # 39; 300 px # 39; 时间=dom.style.height & # 39; 300 px # 39;//访问了三次dom,触发了两次回流和两次重绘
优化后:
.change { ,,,宽度:,300 px; ,,,身高:,300 px; ,,,} ,,,. getelementbyid (& # 39; p # 39;) .className =, & # 39;改变# 39;//只触发一次
2列表类型批量修改,脱离文档流再恢复,利用样式为显示:没有;的节点会在DOM树中而不在渲染树中不会引起重绘回流。
如果要在一个DOM集合中,给每个DOM子节点加一个类,我们可以遍历给每一个节点都加上类,这样就触发了多次的重绘和回流
/*,//需要加入的样式 .change { ,,,宽度:,300 px; ,,,身高:,300 px; } */var ul =, document.getElementsByTagName (& # 39; ul # 39;) var lis =, document.getElementsByTagName(& # 39;李# 39;), 时间=ul.style.display & # 39;没有# 39; (var 小姐:=,0;,小姐:& lt;, lis.length;,我+ +),{ ,,,lis[我].className =, & # 39;改变# 39;; ,,,,} ,,,,ul.style.display =, & # 39;块# 39;
3, DocumentFragment
虚拟DOM其实就是一个对象,js提供了reateDocumentFragment()方法用于创建一个空的虚拟节点对象,DocumentFragment节点不属于文档树,当需要添加多个DOM元素时,如果先将这些元素添加到DocumentFragment中,然后再将DocumentFragment对象添加到渲染树上,会减少页面渲染DOM的次数,效率会明显提升。
var frag =, document.createDocumentFragment(),//创建一个虚拟节点对象 (var 小姐:=,0;,小姐:& lt;, 10;,我+ +),{ ,,,var li =, document.createElement (“li") ,,,li.innerHTML =, & # 39;我是第& # 39;,+,小姐:+,- 1,+,& # 39;个元素& # 39; ,,,frag.appendChild(李),,//将李元素加到虚拟节点对象上 ,,,}, ,,,ul.appendChild(碎片弹),,//将虚拟节点对象加到ul上
<强>其它强>
1,事件委托,利用浏览器事件,冒泡捕获减少页面事件绑定,我们可以指定一个事件处理程序就可以管理某一类型的所有事件。事件函数过多会占用大量内存,而且绑定事件的DOM元素越多会增加访问DOM的次数,对页面的交互就绪时间也会有延迟。
//,事件委托前 var lis =, document.getElementsByTagName(& # 39;李# 39;) (var 小姐:=,0;,小姐:& lt;, lis.length;,我+ +),{ ,,lis[我].onclick =,()函数,{ ,,,,,console.log (this.innerHTML) ,,}},,,,//,利用浏览器事件通过父元素委托事件给子元素 ,,var ul =, document.getElementsByTagName (& # 39; ul # 39;) ul.onclick =,函数(事件),{//也可以做判断给指定的子元素绑定事件 ,,console.log (event.target.innerHTML)};Dom节点怎么进行优化