重排与重绘

重排reflow和重绘repaint

1.重排reflow

reflow指的是重新计算页面布局

某个节点reflow时会重新计算节点的尺寸和位置,而且还有可能触发其子节点,祖先节点和页面上的其他节点reflow,在这之后再触发一次repaint;

render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建,这就成为回流;

每个页面至少需要一次回流,就是在页面第一次加载的时候;

1.1导致reflow的操作有:

1.调整窗口的大小;

2.改变字体;

3.增加或者移除样式表;

4.内容发生变化,比如input中输入文字;

5.激活css伪类,如:hover(IE中为兄弟节点伪类的激活);

6.操作class属性;

7.脚本操作DOM;

8.计算offsetWidthoffsetHeight属性;

1.2触发页面重新布局的一些css属性
1.2.1 盒子模型相关属性会触发重新布局

width ,height,padding,margin,display,border-width,border,min-height

1.2.2 定位属性及浮动也会触发重新布局

top,bottom,left,right,position,float,clear

1.2.3 改变节点内部文字结构也会触发重布局

text-align, overflow-y,font-weight,overflow,font-family,line-height,white-space,font-size

2.重绘repaint

repaint或者redraw遍历所有的节点检测各个节点的可见性,颜色,轮廓,等可见的样式属性,然后根据检测的结果重新更新页面的响应部分;

render tree中的一些元素需要更新属性,而这些属性只会影响元素的外观,风格,而不会影响布局的,比如background-color,被称为重绘;

2.1 只会触发重绘不触发重排的一些css属性:

color,

border-style,border-radius,

visibility,

text-decoration,

background,background-image,background-position,background-repeat,background-size

outline,outline-color,outline-style,outline-width

box-shadow

var bstyle = document.body.style; // cache

bstyle.padding = "20px"; // reflow, repaint
bstyle.border = "10px solid red"; //  再一次的 reflow 和 repaint

bstyle.color = "blue"; // repaint
bstyle.backgroundColor = "#fad"; // repaint

bstyle.fontSize = "2em"; // reflow, repaint

// new DOM element - reflow, repaint
document.body.appendChild(document.createTextNode('dude!'));

注意: 每修改一次样式,他就会reflow或者repaint一次,一般来说,浏览器会把这样的操作积攒一批,然后做一次reflow,这又叫异步reflow或者增量异步reflow,但是有些情况浏览器不会这样,例如:resize窗口,改变页面的默认字体,这些操作,页面会了立马进行reflow;

3.减少重排和重绘

重绘和回流在实际开发中很难避免,要尽量减少这种行为发生;

1.js尽量少访问dom节点和css属性,尽量不要过多的频繁去增加,修改,删除元素,这样可能会频繁的导致页面reflow,可以先把该dom节点抽离到内存中进行复杂的操作然后在display到页面上,(需要DOM)

2.减少不必要的DOM层级(DOM depth),改变DOM树中的一级会导致所有层级改变,上至根部,下至改变节点的子节点,这导致大量时间耗费在执行reflow上面;

3.不要通过父级来改变元素样式,最好直接改变子元素样式,改变子元素样式尽可能不影响父级元素和兄弟元素的大小和尺寸;

4.尽量通过class来设计元素样式,切忌用style多次操作单个属性;

5.尽可能的为产生动画的HTML元素使用fixedabsoluteposition,那么修改他们的css是不会reflow的;

6.img标签要设置宽高,以减少重排和重绘;

7.把DOM离线后修改,如将一个dom脱离文档流,如display:none,在修改属性,这里只发生一次回流;

8.尽量用transform来做形变和位移,不会造成回流;

9.权衡速度的平滑,比如实现一个动画,以1个像素为单位的位移这样最平滑,但是reflow就会过于频繁,CPU很快就会被完全占用,如果以3个像素为单位移动就会好很多;

10.不要用tables布局的另一个原因就是tables中某个元素一旦触发reflow就会导致table里所有的其他元素reflow,在适合用tables的场合,可以设置table-layoutautofixed

11.避免不必要的复杂的css选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的CPU;

注意: display:none会触发reflow,而visibility:hidden只会触发repaint,因为没有发现位置变化;

总结:

1. 重排:元素的尺寸变化,位置变化;
2. 重绘:元素的颜色,背景,边框,轮廓变化,但是元素的几何尺寸没有变;
3. `reflow`的成本比`repaint`成本高的多的多,`DOM Tree`里的每个节点都会有`reflow`方法,一个节点的~很可能会导致子节点,甚至父节点以及同级节点的`reflow`,在一些高性能的电脑上也许还没什么,但是如果`reflow`发生在手机上,那么这个过程是非常痛苦和耗电的;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值