博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从重绘重排角度讲解transform的动画性能
阅读量:6581 次
发布时间:2019-06-24

本文共 2290 字,大约阅读时间需要 7 分钟。

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...

Secret message
...

构造的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, offsetHeightscrollTop, scrollLeft, scrollWidth, scrollHeightclientTop, clientLeft, clientWidth, clientHeightgetComputedStyle() (currentStyle in IE)

因此,尽量不要在修改样式或者布局信息时查询样式,因为查询的时候会强制重排,导致浏览器无法优化多次重排。


使用绝对位置定位页面上的动画元素,将其脱离文档流,可以有效的防止重排。比如有时候做动画特效时,我们通过设置position:absolute可以有效的减少重排。这让我想到,以前做动画的时候通过修改margin-left属性而不是left属性绝对是一个很不好的做法。

transform是否可以避免重排重绘问题

那么使用CSS3的transform来实现动画是否可以避免重排问题?或者说浏览器针对这一部分做了其他优化?

经过一番查找,答案如下:

CSS的最终表现分为以下四步:Recalculate Style -> Layout -> Paint Setup and Paint -> Composite Layers

按照中文的意思大致是 查找并计算样式 -> 排布 -> 绘制 -> 组合层

这上面的几个步骤有点类似于上文说到的重排必定导致重绘,而查询属性会强制发生重排。所以上文提到的重排重绘内容可以结合这里进行理解。

由于transform是位于Composite Layers层,而widthleftmargin等则是位于Layout层,在Layout层发生的改变必定导致Paint Setup and Paint -> Composite Layers,所以相对而言使用transform实现的动画效果肯定比left这些更加流畅。

而且就算抛开这一角度,在另一方面浏览器也会针对transform等开启GPU加速。

参考文章

写完文章后又重新查了一下关于CSS3动画性能方面的文章,发现大漠老师写的这篇很不错,而且跟自己理解的观点有部分相似,先放上来,之后再认真看。

转载地址:http://jvino.baihongyu.com/

你可能感兴趣的文章
软工第二周个人作业
查看>>
不固定个数组,进行一一对应的组合,js将多个数组实现排列组合
查看>>
一个陌生女人的来信
查看>>
SqlServer和Oracle临时表生命周期
查看>>
jquery判断文本框输入的是非数字内容(交流QQ群:452892873)
查看>>
为知笔记-艾宾浩斯遗忘曲线复习插件
查看>>
20050616:今天跟老外第一次讲E文,我说:
查看>>
实验三—单臂路由
查看>>
Python之定义函数
查看>>
Linux下编译安装PHP7.2
查看>>
使用vue如何默认选中单选框
查看>>
pageContext.request.contextPath} JSP取得绝对路径
查看>>
毕业设计进度日志02
查看>>
linux配置java环境变量
查看>>
cocos2d-x遍历zip某个目录(可用于android中apk包的文件访问)
查看>>
IO中同步与异步,阻塞与非阻塞区别(转)
查看>>
数据库升级层
查看>>
css之postion定位
查看>>
补第一阶段冲刺站立会议2(应发表日期5月14日)
查看>>
jquery常见问题
查看>>