关于重绘and重排

在研究CSS3动画性能的时候,看到了重排两个字。

突然想到自己虽然听说过这么个东东,但一直也没深入研究之。

趁着当下正好有研究的劲头,所以一不做二不休,把这个point也给学习了。

同样是一番查找资料...不过这次我得跟作者和原文say sorry了...

因为...我在整理的过程中没注意mark下原文的url...so~~~

主会原谅我的...

浏览器的工作流程

1.浏览器会解析三个东西:

HTML/SVG/XHTML,事实上,Webkit 有三个 C++ 的类对应这三类文档。解析这三种文件会产生一个 DOM Tree。

CSS,解析 CSS 会产生 CSS Rule Tree。

Javascript脚本,主要是通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree。

2.解析完成后,浏览器引擎会通过 DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree。

注意:Rendering Tree 并不等同于 DOM Tree,因为一些像 Header 或 display:none 的东东是不会出现在渲染树中的。

CSS Rule Tree 主要是为了完成匹配并把 CSS Rule 附到 Rendering Tree 上的每个 Element。也就是 DOM 结点。也就是所谓的 Frame。

然后,计算每个 Element 的位置,这又叫 layout 和 reflow 过程。

3.通过调用操作系统 Native GUI 的 API 绘制。

重绘和重排的概念

Repaint —— 重绘。屏幕的一部分要重画,比如某个CSS的背景色变了。但是元素的几何尺寸没有变。

Reflow —— 重排。意味着元件的几何尺寸变了,我们需要重新验证并计算 Render Tree。是 Render Tree 的一部分或全部发生了变化。这就是 Reflow,或是 Layout。(HTML 使用的是 flow based layout,也就是流式布局,所以,如果某元件的几何尺寸发生了变化,需要重新布局,也就叫 reflow)reflow 会从 <html> 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置,在 reflow 过程中,可能会增加一些 frame,比如一个文本字符串必需被包装起来。

重排的成本比重绘的成本高得多的多。DOM Tree 里的每个结点都会有 reflow 方法,一个结点的 reflow 很有可能导致子结点,甚至父点以及同级结点的 reflow。在一些高性能的电脑上也许还没什么,但是如果 reflow 发生在手机上,那么这个过程是非常痛苦和耗电的。

多说两句关于滚屏的事,通常来说,如果在滚屏的时候,我们的页面上的所有的像素都会跟着滚动,那么性能上没什么问题,因为我们的显卡对于这种把全屏像素往上往下移的算法是很快。但是如果你有一个 fixed 的背景图,或是有些 Element 不跟着滚动,有些 Elment 是动画,那么这个滚动的动作对于浏览器来说会是相当相当痛苦的一个过程。你可以看到很多这样的网页在滚动的时候性能有多差。因为滚屏也有可能会造成 reflow。

由于浏览器的流布局,对渲染树的计算通常只需要遍历一次就可以完成。但 table 及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,通常要花3倍于同等元素的时间。这也是为什么我们要避免使用 table 做布局的一个原因。此外,使用 table 的话,可能很小的一个小改动会造成整个 table 的重新布局。

常见的触发重排的操作

1.DOM元素的几何属性变化。

当DOM元素的几何属性变化时,渲染树中的相关节点就会失效,浏览器会根据DOM元素的变化重建构建渲染树中失效的节点。之后,会根据新的渲染树重新绘制这部分页面。而且,当前元素的重排也许会带来相关元素的重排。例如,容器节点的渲染树改变时,会触发子节点的重新计算,也会触发其后续兄弟节点的重排,祖先节点需要重新计算子节点的尺寸也会产生重排。最后,每个元素都将发生重绘。可见,重排一定会引起浏览器的重绘,一个元素的重排通常会带来一系列的反应,甚至触发整个文档的重排和重绘,性能代价是高昂的。

2.DOM树的结构变化。

当DOM树的结构变化时,例如节点的增减、移动等,也会触发重排。浏览器引擎布局的过程,类似于树的前序遍历,是一个从上到下从左到右的过程。通常在这个过程中,当前元素不会再影响其前面已经遍历过的元素。所以,如果在body最前面插入一个元素,会导致整个文档的重新渲染,而在其后插入一个元素,则不会影响到前面的元素。

3.获取某些属性。

浏览器引擎可能会针对重排做了优化。比如Opera,它会等到有足够数量的变化发生,或者等到一定的时间,或者等一个线程结束,再一起处理,这样就只发生一次重排。但除了渲染树的直接变化,当获取一些属性时,浏览器为取得正确的值也会触发重排。这样就使得浏览器的优化失效了。

这些属性包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。所以,在多次使用这些值时应进行缓存。

此外,改变元素的一些样式,调整浏览器窗口大小等等也都将触发重排。

减少重排次数和缩小重排影响范围的一些方法

1.将多次改变样式属性的操作合并成一次操作。例如:

<script>
var changeDiv = document.getElementById(‘changeDiv‘);
changeDiv.style.color = ‘#093‘;
changeDiv.style.background = ‘#eee‘;
changeDiv.style.height = ‘200px‘;
</script>

可以合并为:

<style>
div.changeDiv {
    background: #eee;
    color: #093;
    height: 200px;
}
</style>

<script>
document.getElementById(‘changeDiv‘).className = ‘changeDiv‘;
</script>

因为多次改变属性的操作,当中包含N个会触发重排的属性改变,就会触发N次重排。将其合并后,就只触发一次了。

2.将需要多次重排的元素,position 属性设为 absolute 或 fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。

3.在内存中多次操作节点,完成后再添加到文档中去。

例如要异步获取表格数据,渲染到页面。可以先取得数据后在内存中构建整个表格的html片段,再一次性添加到文档中去,而不是循环添加每一行。

4.由于 display 属性为 none 的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。

如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发2次重排。

5.在需要经常取那些引起浏览器重排的属性值时,要缓存到变量。

这些属性包括:offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。

所以,在多次使用这些值时应进行缓存。

6.不要在css里面写expression,如果css里有expression,很小的一个行为都有可能重新计算一遍。

时间: 2024-12-22 01:10:41

关于重绘and重排的相关文章

浏览器的重绘与重排

在项目的交互或视觉评审中,前端同学常常会对一些交互效果质疑,提出这样做不好那样做不好.主要原因是这些效果通常会产生一系列的浏览器重绘(redraw)和重排(reflow),需要付出高昂的性能代价.那么,什么是浏览器的重绘和重排呢?二者何时发生以及如何权衡?如何在具体的开发过程中将重绘和重排引发的性能问题考虑进去?本文期待可以部分解释以上三个问题. 浏览器从下载文档到显示页面的过程是个复杂的过程,这里包含了重绘和重排.各家浏览器引擎的工作原理略有差别,但也有一定规则.简单讲,通常在文档初次加载时,

浏览器的重绘和重排(转)

浏览器从下载文档到显示页面的过程是个复杂的过程,这里包含了重绘和重排.各家浏览器引擎的工作原理略有差别,但也有一定规则.简单讲,通常在文档初次加载时,浏览器引擎会解析HTML文档来构建DOM树,之后根据DOM元素的几何属性构建一棵用于渲染的树.渲染树的每个节点都有大小和边距等属性,类似于盒子模型(由于隐藏元素不需要显示,渲染树中并不包含DOM树中隐藏的元素).当渲染树构建完成后,浏览器就可以将元素放置到正确的位置了,再根据渲染树节点的样式属性绘制出页面.由于浏览器的流布局,对渲染树的计算通常只需

浏览器渲染页面的过程,以及重绘与重排

浏览器的渲染过程 1,浏览器解析html源码,然后创建一个 DOM树.在DOM树中,每一个HTML标签都有一个对应的节点,并且每一个文本也都会有一个对应的文本节点.DOM树的根节点就是 documentElement,对应的是html标签. 2,浏览器解析CSS代码,计算出最终的样式数据.对CSS代码中非法的语法她会直接忽略掉.解析CSS的时候会按照如下顺序来定义优先级:浏览器默认设置,用户设置,外链样式,内联样式,html中的style. 3,构建出DOM树,并且计算出样式数据后,下一步就是构

浏览器的重绘和重排的影响

浏览器下载完页面中全部的组件之后,会解析生成两个内部数据结构: 1.  DOM树:表示页面结构 2. 表示DOM节点怎样显示 当DOM和渲染树构建完毕之后,浏览器就開始显示(绘制)页面元素.当DOM的变化影响了元素的几何属性(如改变边框或者高度)浏览器须要又一次计算元素的几何属性.相同其它元素的几何属性和位置也会受到影响.浏览器会使中受到影响的部分失效,并又一次构造渲染树.这个过程被称为所谓的"重排".完毕重排后.浏览器会又一次绘制受影响的部分到屏幕中,这个过程被称为"重绘&

重绘和重排

重绘:当元素的一部分属性发生改变, 如外观.背景.颜色等不会引起布局变化, 只需要浏览器根据元素的新属性重新绘制, 使元素呈现新的外观叫做重绘. 重排(回流):当render树中的一部分或者全部因为大小边距等问题发生改变而需要DOM树重新计算的过程 所以简单的来说就是.不会引起布局的变化,叫做重绘. 会引起布局的变化,叫做重排(回流) 所以在我们平时写css的时候,还是要按照html中类的顺序来写. 否者可能会造成重排,重拍是需要消耗浏览器性能的哈. 引起重排的地方 1.添加.删除可见的dom

重绘(repaints)与重排(reflows)

当页面布局和几何属性改变时就需要"重排" 避免在修改样式的过程中使用 offsetTop, scrollTop, clientTop, getComputedStyle() 这些属性, 它们都会刷新渲染队列 最小化重绘和重排, 尽量一次处理a. 使元素脱离文档流(隐藏元素),进行处理后,再显示元素b. 使用 documentFragment 或 innerHTMLc. 将原始元素拷贝到一个脱离文档的节点中, 修改副本, 完成后再替换原始元素

哪些情况下会导致重排或重绘的发生?请给出性能优化的建议。

1.简述重排的概念浏览器下载完页面中的所有组件(HTML.JavaScript.CSS.图片)之后会解析生成两个内部数据结构(DOM树和渲染树),DOM树表示页面结构,渲染树表示DOM节点如何显示.重排是DOM元素的几何属性变化,DOM树的结构变化,渲染树需要重新计算.2.简述重绘的概念重绘是一个元素外观的改变所触发的浏览器行为,例如改变visibility.outline.背景色等属性.浏览器会根据元素的新属性重新绘制,使元素呈现新的外观.由于浏览器的流布局,对渲染树的计算通常只需要遍历一次就

css的重排与重绘

一直在做pc页面的部分,由于网速快,看上去css的写法并没有什么影响所以对css的要求也没怎么注意过,最近在做一些手机端的东西,发现真的差好多,特别是再搭配上js效果时一些延迟更是让人接受不了.在这个快餐的时代,确实导致手机端更具有市场,搭乘地铁的时间变成人们浏览新闻,玩游戏,甚至是购物的时间,此时用户应用的设备多数会是手机,而手机与电脑比起来最大的差距就是网速,这对开发者的要求也就提高了,如何能够加快加载减少响应时间就变成了开发者永恒不变的话题.目前虽然有很多的前辈们已经针对这个现状提出了很多

浏览器渲染页面的过程,以及重排和重绘(转)

前言 写得比我的文字好,有逻辑! 浏览器的渲染过程 1,浏览器解析html源码,然后创建一个 DOM树.在DOM树中,每一个HTML标签都有一个对应的节点,并且每一个文本也都会有一个对应的文本节点.DOM树的根节点就是 documentElement,对应的是html标签. 2,浏览器解析CSS代码,计算出最终的样式数据.对CSS代码中非法的语法她会直接忽略掉.解析CSS的时候会按照如下顺序来定义优先级:浏览器默认设置,用户设置,外链样式,内联样式,html中的style. 3,构建出DOM树,