当前位置: 首页 > Web前端 > HTML

浏览器的回流和重绘及其优化方法

时间:2023-04-02 16:16:48 HTML

推荐知识:基本的HTML,基本的JavaScript,以及一些css工作原理的知识浏览器的渲染原理css的加载和解析不会阻塞html文档的解析css的执行会阻塞js的执行,js的执行必须等到CSSOM生成。js的执行会阻塞html文档的解析,而解析html和显示css必须完全解析完才能进入生成渲染树的环节。浏览器向服务器请求HTML文档,解析后的产物是DOM树(DocumentObjectModel)。如果有CSS,会根据CSS生成CSSOM(CSSObjectModel),然后合并DOM和CSSOM生成RenderTree。有了渲染树,我们知道了所有节点的样式后,根据这些节点和样式计算出它们在浏览器中的确切大小和位置,这就是布局。最后将节点绘制到浏览器。创建DOM树—创建CSSOM树—执行脚本—生成渲染树—生成布局—绘制回流Reflow(回流)当渲染树的一部分(或全部)因元素的大小、布局、隐藏等发生变化时,Web浏览器重新呈现部分或全部文档的过程。重绘当页面元素样式改变不影响元素在文档流中的位置(如background-color、border-color、visibility)时,浏览器只会将新样式赋予元素并执行重绘操作。因为回流是浏览器中用户主导的模块化操作,了解如何改善回流时间以及了解各种文档属性(DOM节点深度、css渲染效率、各种样式变化的影响)对回流时间的影响对开发人员非常有帮助。有时,即使只回流了一个元素,它的父元素和它后面的任何元素也可能需要回流。当它发生时有很多用户操作和潜在的DHTML更改会触发重排。例如,改变浏览器窗口的大小,使用一些JavaScript方法,包括计算样式,向DOM添加或删除元素,或更改元素的类等。添加或删除可见的DOM元素;元素位置变化;元素大小变化——margin、padding、border、width和height内容变化,比如用户在输入框输入文字引起的计算值width,文字或图片大小变化以及高度变化页面渲染初始化浏览器窗口大小变化——计算resize事件发生时的offsetWidth和offsetHeight属性设置style属性的值Reflow肯定会引起重绘,但是重绘不一定会引起reflow。性能优化Reflow比重绘代价更高,reflow的代价与渲染树中有多少节点需要重建有关;浏览器本身可以进行优化,尽可能减少重绘和回流。如果每一行操作DOM的JS代码都需要回流重绘,浏览器可能会承受不了。因此,很多浏览器都会对这些操作进行优化。浏览器会维护一个队列,把所有会引起回流和重绘的操作都放到这个队列中。当队列中的操作达到一定数量或达到一定时间间隔时,浏览器就会刷新队列并进行批处理。这会将多次回流和重绘变成一次回流重绘。当你向浏览器请求一些样式信息时,浏览器会刷新队列,比如:offsetTop、offsetLeft、offsetWidth、offsetHeightscrollTop/Left/Width/HeightclientTop/Left/Width/Heightwidth、height请求getComputedStyle(),或者IE的currentStyle时你请求上面的一些属性,浏览器需要刷新队列才能给你最准确的值,因为队列中可能有影响这些值的操作。即使你获取的某个元素的布局和样式信息与最近发生或改变的布局信息无关,浏览器也会强行刷新渲染队列。如何减少回流和重绘vars=document.body.style;s.padding="2px";//回流+重绘s.border="1pxsolidred";//再次回流+重绘s.color="blue";//再次重绘s.backgroundColor="#ccc";//重新绘制s.fontSize="14px";//reflow+重绘//添加节点,重绘+Redrawdocument.body.appendChild(document.createTextNode('abc!'));///可以看到DOM元素的每一次样式操作都会引起重绘,并且如果涉及layout,也会造成reflow。1.避免CSS中的回流尽量改变DOM树末尾的class避免设置多层内联样式动画效果适用于position属性为absolute或fixed的元素牺牲流畅度换取速度避免使用table布局避免使用JavaScript在CSSExpression2.JS操作中避免回流并避免逐项更改样式。最好一次性更改样式属性,或者将样式列表定义为类并一次性更改类属性。避免循环遍历DOM。创建一个documentFragment或div,在其上应用所有DOM操作,最后将其添加到window.document。也可以对一个display:none元素进行操作,最后显示出来。因为display:none上的DOM操作不会造成reflow和repaint。避免循环读取offsetLeft等属性。在循环之前保存它们。具有复杂动画的元素的绝对定位。绝对定位让它远离文档,否则会造成父元素和后续元素的大量回流。参考文章:Reflowandrepaint:CSSperformancemakesJavaScriptslow?参考文章:浏览器重绘和回流