dom操作
我个人理解,原生js执行速度快于使用各种框架,
但是他有一个很严重的问题:
就是频繁的dom操作会影响页面渲染性能,在老式的手机上可能会导致卡顿等问题
-
导致重排和重绘的操作:
-
导致重排的操作:
-
添加或删除可见的DOM元素(删除display:none的元素不会影响重排)
-
元素的位置发生变化元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
-
内容发生变化(文字数量或图片大小等等)
-
页面一开始渲染的时候(这肯定避免不了)
-
浏览器的窗口尺寸变化(因为重排是根据视口的大小来计算元素的位置和大小的)
注意: 重排一定会触发重绘,而重绘不一定会重排
根据改变的范围和程度,渲染树中或大或小的部分需要重新计算,有些改变会触发整个页面的重排,比如,滚动条出现的时候或者修改了根节点。
浏览器的优化机制
大多数浏览器都会通过队列化修改并批量执行来优化重排和重绘过程。浏览器会将修改操作放入到队列里,直到过了一段时间或者操作达到了一个阈值,才清空队列。但是!当你获取布局信息的操作的时候,会强制队列刷新,比如当你访问以下属性或者使用以下方法:
offsetTop、offsetLeft、offsetWidth、offsetHeightscrollTop、
scrollLeft、scrollWidth、scrollHeightclientTop、
clientLeft、clientWidth、clientHeight
getComputedStyle()getBoundingClientRect
看到很多地方写的是,减少重排会提升页面渲染:
e.g.
//三次重排
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';
//一次重排
el.style.cssText = 'border-left: 1px;border-right: 2px; padding: 5px';
例子中,有三个样式属性被修改了,每一个都会影响元素的几何结构,引起重排。
大部分现代浏览器都会队列化修改,因此,只会触发一次重排。
重绘:
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
怎么减少回流和重绘
避免触发同步布局事件
读取box的一个offsetWidth等属性值,会会强制浏览器刷新队列,先回流重排,在计算结果。因此可以将offsetWidth保存在变量中;
css3硬件加速(GPU加速)
使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘 。但是对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。
CSS
- 避免使用table布局。
- 尽可能在DOM树的最末端改变class。
- 避免设置多层内联样式。
- 将动画效果应用到position属性为absolute或fixed的元素上,脱离文档流。
- 避免使用CSS表达式(例如:calc())。
网友评论