高频Dom操作,页面性能优化(学习)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高频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操作。

以上是关于高频Dom操作,页面性能优化(学习)的主要内容,如果未能解决你的问题,请参考以下文章

前端页面卡顿?或是DOM操作惹的祸,需优化代码

js-关于性能优化的一些学习总结

前端性能优化

JavaScript性能优化 DOM编程

js性能优化篇创建文档碎片

JavaScript性能优化