摘要:完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘。重排必然导致重绘,所以重排更加恶心。使用绝对位置定位页面上的动画元素,将其脱离文档流,可以有效的防止重排。
render树的构建
浏览器取回代码后,首先会构造DOM树,根据HTML标签,构造DOM树。
之后会解析CSS样式,解析的顺序是浏览器的样式 -> 用户自定义的样式 -> 页面的link标签等引进来的样式 -> 写在style标签里面的内联样式
最后根据DOM树以及解析的CSS样式,构造RENDER树,在RENDER树中,会把DOM树中没有的元素给去除,比如head标签以及里面的内容,以及display:none的元素也会被去除。
一旦RENDER树构建完成,浏览器会把树里面的内容绘制在屏幕上。
Beautiful page Once upon a time there was a looong paragraph...
...
构造的DOM树如下
documentElement (html) head title body p [text node] div [text node] div img ...
RENDER树如下
root (RenderView) body p line 1 line 2 line 3 ... div img ...重绘(repaint)和重排(reflow)
当DOM的变化影响了元素的几何属性(宽或高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘。并不是所有的DOM变化都会影响几何属性,比如改变一个元素的背景色并不会影响元素的宽和高,这种情况下只会发生重绘。
重排必然导致重绘,所以重排更加恶心。其实我们一直研究的应该是怎么避免触发多次重排。
重排何时发生添加或者删除可见的DOM元素 元素位置改变 元素尺寸改变 元素内容改变(例如:一个文本被另一个不同尺寸的图片替代) 页面渲染初始化(这个无法避免) 浏览器窗口尺寸改变浏览器的自动优化
var ele = document.getElementById("myDiv"); ele.style.borderLeft = "1px"; ele.style.borderRight = "2px"; ele.style.padding = "5px";
乍一想,元素的样式改变了三次,每次改变都会引起重排和重绘,所以总共有三次重排重绘过程,但是浏览器并不会这么笨,它会把三次修改“保存”起来(大多数浏览器通过队列化修改并批量执行来优化重排过程),一次完成!但是,有些时候你可能会(经常是不知不觉)强制刷新队列并要求计划任务立即执行。获取布局信息的操作会导致队列刷新,比如:
offsetTop, offsetLeft, offsetWidth, offsetHeight scrollTop, scrollLeft, scrollWidth, scrollHeight clientTop, clientLeft, clientWidth, clientHeight getComputedStyle() (currentStyle in IE)
因此,尽量不要在修改样式或者布局信息时查询样式,因为查询的时候会强制重排,导致浏览器无法优化多次重排。
使用绝对位置定位页面上的动画元素,将其脱离文档流,可以有效的防止重排。比如有时候做动画特效时,我们通过设置position:absolute可以有效的减少重排。这让我想到,以前做动画的时候通过修改margin-left属性而不是left属性绝对是一个很不好的做法。
transform是否可以避免重排重绘问题那么使用CSS3的transform来实现动画是否可以避免重排问题?或者说浏览器针对这一部分做了其他优化?
经过一番查找,答案如下:
CSS的最终表现分为以下四步:Recalculate Style -> Layout -> Paint Setup and Paint -> Composite Layers
按照中文的意思大致是 查找并计算样式 -> 排布 -> 绘制 -> 组合层
这上面的几个步骤有点类似于上文说到的重排必定导致重绘,而查询属性会强制发生重排。所以上文提到的重排重绘内容可以结合这里进行理解。
由于transform是位于Composite Layers层,而width、left、margin等则是位于Layout层,在Layout层发生的改变必定导致Paint Setup and Paint -> Composite Layers,所以相对而言使用transform实现的动画效果肯定比left这些更加流畅。
而且就算抛开这一角度,在另一方面浏览器也会针对transform等开启GPU加速。
参考文章
https://www.html5rocks.com/en...
http://www.phpied.com/renderi...
http://www.cnblogs.com/zichi/...
写完文章后又重新查了一下关于CSS3动画性能方面的文章,发现大漠老师写的这篇很不错,而且跟自己理解的观点有部分相似,先放上来,之后再认真看。
https://www.w3cplus.com/anima...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/116587.html
摘要:完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘。重排必然导致重绘,所以重排更加恶心。使用绝对位置定位页面上的动画元素,将其脱离文档流,可以有效的防止重排。 render树的构建 showImg(https://segmentfault.com/img/remote/1460000006908155?w=630&h=292); 浏览器取回代码后,首先会构造DOM树,根据H...
摘要:完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘。重排必然导致重绘,所以重排更加恶心。使用绝对位置定位页面上的动画元素,将其脱离文档流,可以有效的防止重排。 render树的构建 showImg(https://segmentfault.com/img/remote/1460000006908155?w=630&h=292); 浏览器取回代码后,首先会构造DOM树,根据H...
摘要:就如上面的概念一样,单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分。因为队列中,可能会有影响到这些值的操作,为了给我们最精确的值,浏览器会立即重排重绘。 showImg(http://ww1.sinaimg.cn/large/005Y4rCogy1fya3fh2jm3j30ku0dwtb2.jpg); 很多人都知道要减少浏览...
摘要:对于复杂动画效果使用绝对定位让其脱离文档流对于复杂动画效果,由于会经常的引起回流重绘,因此,我们可以使用绝对定位,让它脱离文档流。硬件加速加速比起考虑如何减少回流重绘,我们更期望的是,根本不要回流重绘。 回流和重绘可以说是每一个web开发者都经常听到的两个词语,我也不例外,可是我之前一直不是很清楚这两步具体做了什么事情。最近由于部门内部要做分享,所以对其进行了一些研究,看了一些博客和书...
阅读 1799·2021-11-22 09:34
阅读 3082·2019-08-30 15:55
阅读 661·2019-08-30 15:53
阅读 2050·2019-08-30 15:52
阅读 2998·2019-08-29 18:32
阅读 1988·2019-08-29 17:15
阅读 2391·2019-08-29 13:14
阅读 3556·2019-08-28 18:05