你的位置:首页 > Java教程

[Java教程]高频Dom操作,页面性能优化(学习)

1.1 DOM操作对页面的影响

通过js操作DOM的代价很高,影响页面性能的主要问题有如下几点:

  • 访问和修改DOM元素

  • 修改DOM元素的样式,导致重绘重排

  • 通过对DOM元素的事件处理,完成与用户的交互功能

DOM的修改会导致重绘重排

  • 重绘是指一些样式的修改,元素的位置和大小都没有改变;
  • 重排是指元素的位置或尺寸发生了变化,浏览器需要重新计算渲染树,而新的渲染树建立后,浏览器会重新绘制受影响的元素。

页面重绘的速度要比页面重排的速度快,在页面交互中要尽量避免页面的重排操作。浏览器不会在js执行的时候更新DOM,而是会把这些DOM操作存放在一个队列中,在js执行完之后按顺序一次性执行完毕,因此在js执行过程中用户一直在被阻塞。

2.1 导致页面重排的一些操作:

  • 内容改变

    • 文本改变或图片尺寸改变

  • DOM元素的几何属性的变化

    • 例如改变DOM元素的宽高值时,原渲染树中的相关节点会失效,浏览器会根据变化后的DOM重新排建渲染树中的相关节点。如果父节点的几何属性变化时,还会使其子节点及后续兄弟节点重新计算位置等,造成一系列的重排。

  • DOM树的结构变化

    • 添加DOM节点、修改DOM节点位置及删除某个节点都是对DOM树的更改,会造成页面的重排。浏览器布局是从上到下的过程,修改当前元素不会对其前边已经遍历过的元素造成影响,但是如果在所有的节点前添加一个新的元素,则后续的所有元素都要进行重排。

  • 获取某些属性

    • 除了渲染树的直接变化,当获取一些属性值时,浏览器为取得正确的值也会发生重排,这些属性包括:offsetTopoffsetLeft、 offsetWidthoffsetHeightscrollTopscrollLeftscrollWidthscrollHeight、 clientTopclientLeftclientWidthclientHeightgetComputedStyle()

  • 浏览器窗口尺寸改变

    • 窗口尺寸的改变会影响整个网页内元素的尺寸的改变,即DOM元素的集合属性变化,因此会造成重排。

 

2.2 导致页面重绘的操作

  • 应用新的样式或者修改任何影响元素外观的属性

    • 只改变了元素的样式,并未改变元素大小、位置,此时只涉及到重绘操作。

  • 重排一定会导致重绘

    • 一个元素的重排一定会影响到渲染树的变化,因此也一定会涉及到页面的重绘。

3. 针对操作DOM的性能优化方法总结

为了减少DOM操作对页面性能产生的影响,在实现页面的交互效果时一定要注意一下几点:

1.减少在循环内进行DOM操作,在循环外部进行DOM缓存

1 //优化前代码2 function Loop() {3 console.time("loop1");4 for (var count = 0; count < 15000; count++) {5  document.getElementById('text').innerHTML += 'dom';6  }7 console.timeEnd("loop1");8 }
View Code
 1 //优化后代码 2 function Loop2() { 3  console.time("loop2"); 4  var content = ''; 5  for (var count = 0; count < 15000; count++) { 6   content += 'dom'; 7  } 8  document.getElementById('text2').innerHTML += content; 9  console.timeEnd("loop2");10 }
View Code

2.只控制DOM节点的显示或隐藏,而不是直接去改变DOM结构

3.操作DOM前,先把DOM节点删除或隐藏

1 var list1 = $(".list1");2 list1.hide();3 for (var i = 0; i < 15000; i++) {4  var item = document.createElement("li");5  item.append(document.createTextNode('0'));6  list1.append(item);7 }8 list1.show();
View Code

display属性值为none的元素不在渲染树中,因此对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行多次DOM操作,可以先将其隐藏,操作完成后再显示。这样只在隐藏和显示时触发2次重排,而不会是在每次进行操作时都出发一次重排。

4.最小化重绘和重排

1 //优化前代码2 var element = document.getElementById('mydiv');3 element.style.height = "100px"; 4 element.style.borderLeft = "1px"; 5 element.style.padding = "20px";
View Code
 1 //优化后代码 2 //js操作 3 .newStyle {  4  height: 100px;  5  border-left: 1px;  6  padding: 20px;  7 }  8 element.className = "newStyle"; 9 //jquery操作10 $(element).css({11  height: 100px; 12  border-left: 1px; 13  padding: 20px;14 })
View Code

在未优化代码中,每对element进行一次样式更改都会影响该元素的集合结构,最糟糕情况下会触发三次重排。优化方式:利用js或jquery对该元素的class重新赋值,获得新的样式,这样减少了多次的DOM操作。