1、浏览器的渲染机制
浏览器渲染展示网页的过程,大致分为以下几个步骤:
也就是说浏览器下载完页面所有的资源后,就要开始构建DOM树,和DOM树同期会构建Style Tree。DOM树与Style Tree合并为渲染树(Render Tree)
DOM树是用来表示页面中的结构,而渲染树表示页面的节点如何显示。
一旦渲染树构建完成,就要开始绘制(paint)页面元素了。
2、认识重排与重绘
当DOM的变化引发了元素几何属性的变化,比如改变元素的宽高,元素的位置,导致浏览器不得不重新计算元素的几何属性,并重新构建渲染树,这个过程称为“重排”。完成重排后,要将重新构建的渲染树渲染到屏幕上,这个过程就是“重绘”。
简单的说,重排负责元素的几何属性更新,重绘负责元素的样式更新。而且,重排必然带来重绘,但是重绘未必带来重排。比如,改变某个元素的背景,这个就不涉及元素的几何属性,所以只发生重绘。
简单总结:
1、当render tree中的一部分(或全部),因为元素的规模尺寸、布局、隐藏等改变而需要重新构建,这就是重排(reflow)
(1)每个页面至少回流一次,即页面首次加载
(2)回流时,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树
(3)回流完成后,浏览器会重新绘制受影响的部分,是重绘过程
2、当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格,而不影响布局(例如:background-color),则称为重绘(repaints)
特点:回流必将引起重绘,重绘不一定引起回流 回流比重绘的代价更高
3、重排触发机制
上面已经讲到,重排发生的根本原因就在于元素的几何属性发生改变,那我们就从几何属性的角度出发,去探寻它的触发机制。
(1)添加或者删除可见的DOM元素;
(2)元素位置改变;
(3)元素尺寸改变——边距、填充、边框、宽度和高度
(4)内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;
(5)页面渲染初始化;
(6)浏览器窗口尺寸改变——resize事件发生时;
(7)激活伪类,如:hover
(8)操作class属性
4、重绘触发机制
元素的属性或者样式发生变化。
5、如何进行性能优化
重绘和重排的开销是非常昂贵的,如果我们不停的在改变页面的布局,就会造成浏览器耗费大量的开销在进行页面的计算,这样的话,我们页面在用户使用起来,就会出现明显的卡顿。现在的浏览器其实对重排进行了一定的优化。把多次的重排重绘变成一次重排重绘
原理:浏览器会维护一个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会刷新队列,进行一个批处理。
但是,有些时候我们会强制进行刷新队列,并要求计划任务立刻执行。这些方法包括:
(1)offsetTop,offsetLeft,offsetWidth,offsetHeight
(2)scrollTop,scrollLeft,scrollWidth,scrollHeight
(3)clientTop,clientLeft,clientWidth,clientHeight
(4)getComputedStyle()
以上的属性和方法需要返回最新的布局信息,因此浏览器不得不执行渲染队列中的“待处理变化”并触发重排,以返回正确的值。因此,修改样式的过程中,最好避免使用以上的属性或者是方法。
所以我们需要一些方法,尽可能的避免或减少浏览器的重排、重绘。
1、合并对Dom的多次修改
在以上打代码中,我们能够看到对元素的几何属性发生了四次的修改,因此,上面的代码中会触发四次的重排和重绘。我们可以将对元素的四次修改合并成一次修改,这样,就只会触发一次重排重绘。修改后的代码如下:
2、减少对style样式的请求
到此这篇重绘和重排和回流(重绘和重排和回流哪个好)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!(1)添加css样式,而不是利用js控制样式
(2)让要操作的元素进行“离线处理”,处理完后一起更新
当用DocumentFragment进行缓存操作,引发一次重排和重绘
使用display:none技术,只引发两次重排和重绘
使用cloneNode(true or false)和replaceChild技术,引发一次重排和重绘
(3)直接改变className,如果动态改变样式,则使用cssText(考虑没有优化的浏览器)
elem.style.left = x + “px”;
elem.style.top = y + “px”;
改为:
elem.style.cssText += “;left: " + x + “px;top: " + y + “px;”;
(4)不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,利用缓存
(5)让元素脱离动画流,减少回流的Render Tree的规模
$(”#block1”).animate({left:50});
$("#block2").animate({marginLeft:50});
(6)将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位;
(7)避免使用table布局:尽量不要使用表格布局,如果没有定宽表格一列的宽度由最宽的一列决定,那么很可能在最后一行的宽度超出之前的列宽,引起整体回流造成table可能需要多次计算才能确定好其在渲染树中节点的属性,通常要花3倍于同等元素的时间。
(8)尽量将需要改变DOM的操作一次完成
(9)尽可能在DOM树的最末端改变class,尽可能在DOM树的里面改变class(可以限制回流的范围)
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/bcyy/15304.html