您的位置:首页 > Web前端 > CSS

[置顶] css重绘与重排详解

2017-07-18 14:13 141 查看
什么是重绘重排呢?重绘重排又会如何影响新能?

浏览器下载完页面中的所有组件——HTML标记、JavaScript、CSS、图片之后会解析生成两个内部数据结构——
DOM树
渲染树


DOM树表示页面结构,渲染树表示DOM节点如何显示。DOM树中的每一个需要显示的节点在渲染树种至少存在一个对应的节点(隐藏的DOM元素disply值为none 在渲染树中没有对应的节点)。渲染树中的节点被称为“帧”或“盒”,符合CSS模型的定义,理解页面元素为一个具有填充,边距,边框和位置的盒子。一旦DOM和渲染树构建完成,浏览器就开始显示(绘制)页面元素。

1、重绘(Repaint)

重绘是一个元素外观的改变所触发的浏览器行为,例如改变outline、背景色等属性。浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。重绘不会带来重新布局,所以并不一定伴随重排。

2、重排(Reflow)

渲染对象在创建完成并添加到渲染树时,并不包含位置和大小信息。计算这些值的过程称为布局或重排

3.常见触发重排的操作(一)

当你请求向浏览器请求一些 style信息的时候,就会让浏览器flush队列,比如:
1. offsetTop, offsetLeft, offsetWidth, offsetHeight

2. scrollTop/Left/Width/Height

3. clientTop/Left/Width/Height

4. width,height
当你请求上面的一些属性的时候,浏览器为了给你最精确的值,需要flush队列,

因为队列中可能会有影响到这些值的操作。即使你获取元素的布局和样式信息跟最近的布局信息差不多,

浏览器都会强行刷新渲染队列。

4.常见触发重排的操作(二)

添加或者删除可见的DOM元素
元素位置改变
元素尺寸改变
元素内容改变(例如:一个文本被另一个不同尺寸的图片替代)
页面渲染初始化(这个无法避免)
浏览器窗口尺寸改变
5.如何解决重绘重排,提高性能

先来看个例子

vartimes=15000;

 

//
code1 每次过桥+重排+重绘

console.time(1);

for(vari=0;i<times;i++){

  document.getElementById('myDiv1').innerHTML+='a';

}

console.timeEnd(1);

 

//
code2 只过桥

console.time(2);

varstr='';

for(vari=0;i<times;i++){

  vartmp=document.getElementById('myDiv2').innerHTML;

  str+='a';

}

document.getElementById('myDiv2').innerHTML=str;

console.timeEnd(2);

 

//
code3

console.time(3);

var_str='';

for(vari=0;i<times;i++){

  _str+='a';

}

document.getElementById('myDiv3').innerHTML=_str;

console.timeEnd(3);

 

//
1: 2874.619ms

//
2: 11.154ms

//
3: 1.282ms

1)对dom操作的次数以及对文档dom的渲染会严重影响性能,主要靠多次更改合并为一次更改从而到提高性能的作用。

2)documentFragment、cloneNode类型的正确使用会减少重排次数(参见高程275页)。

3)将某些经常会重排的元素脱离文档流,不影响页面布局,从而达到减少重排目的。

6.总结

尽量不要在布局信息改变时做查询(会导致渲染队列强制刷新,第3点)
同一个DOM的多个属性改变可以写在一起(减少DOM访问,同时把强制渲染队列刷新的风险降为0,第5点的1))
如果要批量添加DOM,可以先让元素脱离文档流,操作完后再带入文档流,这样只会触发一次重排(第5点的1))
将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。(第5点的3))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: