一、什么是重绘,什么是回流?如何减少回流?
重绘(Repaint):
重绘是指当元素样式发生改变,但不影响其布局的情况下,浏览器重新绘制元素的过程。例如,修改元素的背景颜色、字体颜色等。
回流(Reflow):
回流是指当元素的布局属性发生改变,需要重新计算元素在页面中的布局位置时,浏览器重新进行布局的过程。例如,修改元素的宽度、高度、位置等。回流的成本比重绘高得多,因为它涉及重新计算元素的几何属性和页面布局。而重绘只需要重新绘制已计算好的元素样式。
如何减少:
- 使用 CSS 动画代替 JavaScript 动画:CSS 动画利用 GPU 加速,在性能方面通常比 JavaScript 动画更言效。使用 CSS 的 transform 和 opacity 属性来创建动画效果,而不是改变元素的布局属性,如宽度高度等。
- 使用 translate3d 开启硬件加速:将元素的位移属性设置为 translate3d(,0,0),可以强制使用GPU 加速。这有助于避免回流,并提高动画的流畅度。
- 避免频繁操作影响布局的样式属性:当需要对元素进行多次样式修改时,可以考虑将这些修改合并为一次操作。通过添加/移除 CSS 类来一次性改变多个样式属性,而不是逐个修改。
- 使用 requestAnimationFrame:通过使用 reguestAnimationFrame 方法调度动画帧,可以确保动画在浏览器的重绘周期内执行,从而避免不必要的回流。这种方式可确保动画在最佳时间点进行渲染。使用文档片段(Document Fragment):当需要向 DOM 中插入大量新元素时,可以先将这些元素添加到文档片段中,然后再将整个文档片段一次性插入到 DOM 中。这样做可以减少回流次数。(虚拟 dom vue 的方式)
- 让元素脱离文档流:position:absolute/position:fixed /foat:left,(只是减少回流,不是避免回流。使用 visibility:hidden 替代 display:none: visibility:hidden 不会触发回流,因为元素仍然占据空间,只是不可见。而使用 display:none 则会将元素从渲染树中移除,引起回流。
二、Margin塌陷问题如何解决?BFC是什么?怎么触发BFC
<html>
<head>
<style type="text/css">
.box {
width: 100px;
height: 100px;
background-color:red;
#box1 {
margin-bottom:200px;
#box2 {
margin-top: 100px;
</style>
</head>
<body>
<div id="box1" class="box"></div>
<div id="box2" class="box"></div>
</body>
</html>
margin塌陷:
例子中两个div的间距为200px,是取的重叠部分的最大值(css的外边距合并),如果要间距300px,则需要为div触发BFC。
BFC定义:
全称块级格式化上下文(Block Formatting Context),是一个独立的渲染区域,有独立的渲染规则,与外部元素不会产生影响
BFC触发方式:
- 设置float属性(值不为none)
- 设置position属性为absolute或者fixed
- 设置display属性为inline-block
- 设置overflow属性(值不为visible)