CSS 回流(Reflow)和重绘(Repaint)
回流(Reflow)和重绘(Repaint)是影响网页性能的关键概念。回流指元素几何属性改变触发的布局重新计算,代价较高;重绘则是元素外观样式变化但不影响布局。常见触发因素包括元素尺寸、位置改变(回流)和颜色、背景变化(重绘)。优化建议包括:避免频繁样式操作、使用文档片段批量处理DOM、优先使用transform/opacity等不会触发回流的属性。理解这些机制有助于编写更高效的代码,提升页面性能
基本概念
回流(Reflow) 和 重绘(Repaint) 是浏览器渲染过程中的两个重要概念,它们会影响页面性能。
回流(Reflow)
-
也称为"布局"(Layout)
-
当渲染树中的一部分或全部因为元素的规模尺寸、布局、隐藏等改变而需要重新构建时发生
-
会计算所有受影响元素的几何属性(位置和大小)
-
是开销较大的操作
重绘(Repaint)
-
当元素的外观样式改变但不影响布局时发生(如颜色、背景色等)
-
不需要重新计算几何属性
-
开销相对较小
触发条件
触发回流的操作
-
页面首次渲染
-
浏览器窗口大小改变
-
元素尺寸或位置改变(width, height, margin, padding, border等)
-
元素内容变化(文字数量、图片大小等)
-
添加/删除可见DOM元素
-
激活CSS伪类(:hover等)
-
查询某些属性或调用某些方法(见下文)
触发重绘的操作
-
颜色、背景色等不影响布局的样式变化
-
visibility样式的改变(但display:none会触发回流)
性能影响
回流比重绘的代价更高,因为它会导致浏览器重新计算所有受影响元素的几何属性,并可能导致部分或整个渲染树需要重新构建。
优化建议
-
避免频繁操作样式:最好一次性修改样式,而不是多次修改
// 不好 el.style.margin = '5px'; el.style.padding = '10px'; // 更好 el.style.cssText = 'margin:5px; padding:10px;';
-
使用文档片段(DocumentFragment):批量操作DOM
const fragment = document.createDocumentFragment(); // 添加多个元素到fragment document.body.appendChild(fragment);
-
避免强制同步布局:不要在读取布局属性前修改样式
// 不好 - 强制同步布局 const width = el.offsetWidth; el.style.width = width + 10 + 'px'; // 更好 - 先修改后读取 el.style.width = '100px'; const width = el.offsetWidth;
-
使用transform和opacity:这些属性不会触发回流
-
避免table布局:table中一个小改动可能导致整个table回流
-
CSS优化:
-
避免多层内联样式
-
将动画元素设置为position: absolute/fixed
-
避免CSS表达式
-
常见触发回流的属性和方法
属性(读取时会强制回流)
-
offsetTop/offsetLeft/offsetWidth/offsetHeight
-
scrollTop/scrollLeft/scrollWidth/scrollHeight
-
clientTop/clientLeft/clientWidth/clientHeight
-
getComputedStyle()
-
getBoundingClientRect()
方法(可能触发回流)
-
elem.append()
-
elem.remove()
-
elem.insertBefore()
-
elem.replaceChild()
-
elem.style.setProperty()
-
window.getComputedStyle()
-
elem.scrollIntoView()
-
elem.focus()
理解回流和重绘有助于开发者编写更高效的CSS和JavaScript代码,提升页面性能。
更多推荐
所有评论(0)