单纯说概念就是 浏览器渲染会解析css,dom对吧,如果你更改背景颜色,dom等等就需要重新渲染对吧,这个就是重绘和回流。
复杂一点说概念就是
重绘(Repaint):
定义:重绘是指当元素的样式发生改变,但不影响其布局的情况下,浏览器重新绘制元素的可视部分。
过程:浏览器会根据新的样式属性值更新元素的视觉外观,重新绘制元素的背景色、边框、文本等可视效果。
影响:重绘操作不会影响页面的布局和几何属性,只是重新绘制元素的外观,所以开销相对较小。回流(Reflow):
定义:回流是指当页面的布局发生改变,例如元素的尺寸、位置、显示/隐藏状态等改变时,浏览器重新计算并应用所有受影响元素的几何属性,然后重新排列页面中的元素。
过程:浏览器会从页面的根节点开始递归遍历,并计算每个受影响元素的布局属性,例如位置、尺寸、相对关系等。
影响:回流操作涉及大量的计算和重新排列,会导致整个页面或部分页面的重建,开销较大,可能会引起页面闪烁和性能下降。
在知道什么是重绘和回流以后,如果要搞清楚究竟是怎么回事儿,就需要浏览器大概是怎么做的
简单说就如下
url => dns => ip => tcp => http(get,post..) => 获取响应数据(头,数据等) => 解析html => 构建dom树 => css树 => 执行javascript => 结合dom树,css树 身成 render树。 => 渲染出元素位置和大小(回流) => 绘制元素(重绘)
过程大概就是这样, 这里知道了回流和重绘产生的阶段,但是这里其实没有说一些细节概念,但是和回流和重绘相关。
这就是浏览器渲染的基本流程,为什么要讲这个?为什么要知道图层的概念?
因为重绘和回流可以控制在图层中,可以限制范围,从而提升性能。
从之前讲的基本概念我们可以知道重绘的代价是比较小的
浏览器会根据新的样式属性值更新元素的视觉外观,重新绘制元素的背景色、边框、文本等可视效果。
影响:重绘操作不会影响页面的布局和几何属性,只是重新绘制元素的外观,所以开销相对较小.
因为它不会改变整体大小,不会导致整体大小重新计算,仅仅改变当前部分,所以代价是比较小的。
这里涉及到一个问题,就是重绘的范围, 我在查资料的时候,对于重绘的说法都是只影响当前的元素,那么他是否有可能影响到其他元素呢?
这里是可能触发重绘的操作
重绘的开销其实可以不那么精确计算,因为正常情况下不会出现不停的修改样式,往往是做动画的时候才会出现。这个时候善用 css3动画的gpu加速的特性就好了。
回流就比较简单了,任何改变都可能导致整个页面回流,最简单的例子就是窗口发生改变,那么整个页面也就回流了。
比如你突然改变一个元素的大小,自然会导致问题,这就是应该避免或者优化的东西。
当我们要去修改css,尽量不用使用行内css,多用class,保证修改次数少。
设计 css 的时候,多用选择器。
保证一件事,减少次数,但是这个似乎现在浏览器都做了优化,但是还是需要注意。
在css上注意,在dom操作上也需要注意。
比如我要绑定数据,写一个循环不停的创建,可能会不停的触发回流。
合并就是减少回流次数
首先需要知道什么是同步布局事件,我们刚才看了浏览器执行的流程
dom tree => ccs tree => javascript => render tree => layout.
但是如果遇到一种情况
1 | function a() { |
本来是 javascript 执行以后开始计算整个布局,但是如果你每次都去获取,就会强制计算整个布局,然后返回数据,再一次循环,这个就是问题。
不仅仅是我这种操作会触发
1 | function logBoxHeight() { |
所以javascript获取属性需要谨慎, 前面如果有样式修改,那么再获取就会触发。
简单说就是移动使用transform,来代替top,left。
别用visibility,使用opacity。
如果要写动画,多用可以触发gpu加速的
window.requestAnimationFrame() 是一个用于执行动画的 Web API 方法。它接受一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前被调用。
这里弄清楚了回流和重绘的基本概念,为什么要知道这些概念,从而更好的去提升性能,特别是在一些关键的页面上。
只是现在大家都用框架了,框架帮你做了大部分的事情。