重绘和回流的定义

1.渲染树(render tree)
1.浏览器把获取到的HTML代码解析成一棵DOM树,HTML中的每个标签(tag)都是DOM树中的一个节点,根节点就是我们常用的document对象。DOM树里包含了HTML所有标签,包括display:none隐藏,还有用JS动态添加的元素等;

2.浏览器把所有样式(用户定义的css和用户代理)解析成样式结构体,在解析过程中会去掉浏览器不能识别的样式,比如IE会去掉-moz开头的样式,而Firefox会去掉_开头的样式;

3.DOM树和样式结构体组合后构建render tree(渲染树),render tree类似于DOM树,但区别很大,render tree 能识别样式,render tree的每一个节点都有自己的样式,而且render tree中不包含隐藏的节点(比如display:none的节点,还有head节点),因为这些节点不会用于呈现,而且不会影响呈现。

2.重绘与回流的定义
重绘:当前元素的样式(背景颜色、字体颜色等)发生改变的时候,我们只需要把改变的元素重新的渲染一下即可,重绘对浏览器的性能影响较小,所以 一般不考虑。

发生重绘的情形:改变容器的外观风格等,比如background:black等。改变外观,不改变布局,不影响其他的dom。

回流:是指浏览器为了重新渲染部分或者全部的文档而重新计算文档中元素的位置和几何构造的过程。
因为回流可能导致整个dom树的重新构造,所以是性能的一大杀手
一个元素的回流导致了其所有子元素以及DOM中紧随其后的祖先元素的随后的回流.

3.触发回流的操作
1.调整窗口大小(Resizing the window)

2.改变字体(Changing the font)

3.增加或者移除样式表(Adding or removing a stylesheet)

4.内容变化,比如用户在input框中输入文字(Content changes, such as a user typing text in an input box)

5.激活 CSS 伪类,比如 :hover (IE 中为兄弟结点伪类的激活)(Activation of CSS pseudo classes such as :hover (in IE the activation of the pseudo class of a sibling)

6.操作 class 属性(Manipulating the class attribute)

7.脚本操作 DOM(A script manipulating the DOM)

8.计算 offsetWidth 和 offsetHeight 属性(Calculating offsetWidth and offsetHeight)

9.设置 style 属性的值 (Setting a property of the style attribute)

10.fixed定位的元素,在拖动滚动条的时候会一直回流

如何避免回流
1. 一起变化:如果要改变一个元素的样式,可以将所有样式集中在一个class上面一次变化,而不是变化几次
2. 具有动画效果请使用absolute
3. 避免使用表格布局
4. 不要使用CSS表达式
5. 在最末改变元素
6. 动画移动时候,要控制
比如我们拖动元素时候,我是在他x或者y坐标改变5px才操作,这样虽说降低了平滑度,但是对性能有提高
7. 如果你想让复杂的表现发生改变,例如动画效果,那么请在这个流动线之外实现它。使用position-absolute或position-fixed来实现它。
8. 既然计算offsetWidth也会引起回流,那么就拿一个变量保存它
9. 当我们需要向文档中添加节点时,可以用文档碎片的方式去解决这个问题的,当我们需要给DOM中添加新的元素的时候,先将其放在一个容器中,然后统一添加,这样就只产生了一次回流

防抖和回流都是前端性能优化的重要手段。 防抖指的是在一定时间内,如果事件被多次触发,则只执行最后一次触发的事件。这种方式可以避免因为频繁触发事件而导致的性能消耗。 回流指的是当DOM元素的尺寸、位置等属性发生变化时,浏览器需要重新计算元素的布局并进行重绘,这个过程称为回流回流是一种非常消耗性能的操作,因此应该尽量减少回流的次数。 回流的实现代码如下: ```javascript // 获取 DOM 元素的样式值 function getStyle(el, prop) { return window.getComputedStyle(el, null)[prop]; } // 修改 DOM 元素的样式值 function setStyle(el, prop, val) { el.style[prop] = val; } // 获取 DOM 元素的宽度值 function getWidth(el) { return el.getBoundingClientRect().width; } // 修改 DOM 元素的宽度值 function setWidth(el, val) { setStyle(el, 'width', val + 'px'); } // 修改 DOM 元素的位置 function setPosition(el, x, y) { setStyle(el, 'transform', `translate(${x}px, ${y}px)`); } // 修改 DOM 元素的尺寸和位置 function resizeAndReposition(el, width, x, y) { // 获取当前元素的样式值 const prevWidth = getWidth(el); const prevX = parseInt(getStyle(el, 'left')); const prevY = parseInt(getStyle(el, 'top')); // 如果新的尺寸和位置与当前尺寸和位置不同 if (prevWidth !== width || prevX !== x || prevY !== y) { // 先将元素的尺寸和位置设置为新的值 setWidth(el, width); setPosition(el, x, y); // 然后强制浏览器进行回流 el.getBoundingClientRect(); } } ``` 在上面的代码中,我们定义了一些常用的操作DOM元素的函数,包括获取样式值、修改样式值、获取宽度值、修改宽度值、修改位置等。最后,我们定义了一个函数`resizeAndReposition`,该函数用于修改DOM元素的尺寸和位置,并在必要时强制浏览器进行回流,以避免多次进行回流操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值