css重绘与重排详解

来源:互联网 发布:淘宝网做包邮亏 编辑:程序博客网 时间:2024/06/18 16:45

什么是重绘重排呢?重绘重排又会如何影响新能?

浏览器下载完页面中的所有组件——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.常见触发重排的操作(二)

  1. 添加或者删除可见的DOM元素
  2. 元素位置改变
  3. 元素尺寸改变
  4. 元素内容改变(例如:一个文本被另一个不同尺寸的图片替代)
  5. 页面渲染初始化(这个无法避免)
  6. 浏览器窗口尺寸改变
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.总结

  1. 尽量不要在布局信息改变时做查询(会导致渲染队列强制刷新,第3点)
  2. 同一个DOM的多个属性改变可以写在一起(减少DOM访问,同时把强制渲染队列刷新的风险降为0,第5点的1))
  3. 如果要批量添加DOM,可以先让元素脱离文档流,操作完后再带入文档流,这样只会触发一次重排(第5点的1))
  4. 将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。(第5点的3))
















原创粉丝点击