哪些网站有二维码,wordpress模板修改教程,开网站建设公司怎么样,如何上传网站到云服务器前端知识速记#xff1a;重绘和回流
一、什么是重绘与回流
1. 重绘#xff08;Repaint#xff09;
重绘是指当元素的外观发生变化时#xff0c;浏览器需要重新绘制这些元素。由于这些操作不会改变元素占据的空间#xff0c;因此不需要进行回流。常见的重绘操作包括重绘和回流
一、什么是重绘与回流
1. 重绘Repaint
重绘是指当元素的外观发生变化时浏览器需要重新绘制这些元素。由于这些操作不会改变元素占据的空间因此不需要进行回流。常见的重绘操作包括
元素的颜色、背景色、边框等样式属性发生变化元素的可见性发生变化如 display: none 变为 display: block ps针对这个例子也会触发回流并且是先触发回流再触发重绘 回流Reflow display: none 的元素不会在页面中占据空间也不会参与布局计算。当将其改为 display: block 时元素会重新出现在页面中并占据空间这使得浏览器需要重新计算该元素以及可能受其影响的其他元素的布局信息确定它们在页面上的位置和大小这个重新计算布局的过程就是回流。重绘Repaint 在完成回流确定好元素新的布局信息后浏览器需要根据新的样式和布局将元素绘制到屏幕上更新元素的外观这个过程就是重绘。 感谢 lijibing 大佬指出问题 - 字体样式等
2. 回流Reflow
回流也称为布局重排是指当元素的尺寸、位置或其他影响其布局的属性发生变化时浏览器需要重新计算元素的布局并重新构建渲染树Render Tree的过程。在回流发生时涉及到的元素及其后代会被重新计算并绘制这通常会导致性能下降。常见的回流操作包括
更改元素的尺寸如设置 width、height、padding、border、margin。添加或删除可见的DOM元素包括添加或删除元素。修改元素的内容如文本变化、数量图片数量、大小、字体大小。改变视口如窗口缩放、滚动等。页面初始渲染。浏览器窗口大小改变。激活CSS伪类如 :hover。查询某些属性或调用某些方法如 offsetWidth、scrollTop 等时会引发回流。
值得注意的是回流一定会引起重绘但重绘不一定会导致回流。 例如当你改变一个元素的颜色时浏览器只会进行重绘操作但是当你改变一个元素的宽度时浏览器会进行回流操作。
二、回流的影响范围
回流的影响范围可分为全局和局部。全局回流会影响整个页面的布局导致重新计算所有元素的样式和位置而局部回流只会影响某些特定元素及其后代。
回流的成本通常比重绘大得多因此我们应该尽量减少回流操作以降低页面性能消耗。
三、如何优化回流
要提高性能我们需要减少回流的发生频率特别是控制回流的次数和影响范围。以下是几种有效的优化方案
1. 减少回流次数
核心观念是尽量集中样式修改避免频繁操作DOM。
样式集中处理将样式的修改集中到一个步骤中而不是逐个修改。这可以通过创建一个样式数组通过更改一个元素的 class 来实现样式的切换从而减少操作次数。
// 1. 不集中处理样式直接修改样式属性
document.getElementById(update).addEventListener(click, () {const boxes document.querySelectorAll(.box);boxes.forEach((box) {box.style.width 200px; // 直接修改样式属性box.style.height 200px;box.style.backgroundColor red;box.style.transform translateX(50px);});
});// 1. 减少回流次数通过集中处理样式
document.getElementById(update).addEventListener(click, () {const boxes document.querySelectorAll(.box);boxes.forEach((box) {box.classList.add(new-style); // 通过添加类名来集中更新样式});
});通过变量存储调用 offsetWidth 结果当需要多次获取元素的布局信息如 offsetWidth应将其存储在变量中以避免重复计算从而减少回流。
// 2. 不使用变量存储 offsetWidth 结果多次调用 offsetWidth
document.getElementById(addBox).addEventListener(click, () {const container document.getElementById(container);console.log(Container Width:, container.offsetWidth); // 多次调用 offsetWidthconsole.log(Container Width:, container.offsetWidth); // 多次调用 offsetWidthconsole.log(Container Width:, container.offsetWidth); // 多次调用 offsetWidthconst newBox document.createElement(div);newBox.className box new-style;container.appendChild(newBox);
});// 2. 使用变量存储调用 offsetWidth 结果避免重复计算
const container document.getElementById(container);
const containerWidth container.offsetWidth; // 只计算一次
console.log(Container Width:, containerWidth); // 输出容器宽度 2. 减少回流范围
核心观念是通过精简涉及回流的DOM操作来减小影响范围。常见减少回流范围的操作包括
DOM离线操作在进行多次DOM更新时可以使用文档片段DocumentFragment来批量更新DOM避免频繁的回流。
// 3. DOM 离线操作使用文档片段添加多个元素
document.getElementById(addBox).addEventListener(click, () { const fragment document.createDocumentFragment(); const newBox document.createElement(div); newBox.className box new-style; // 直接添加样式类 fragment.appendChild(newBox); // 一次性添加避免多次回流 container.appendChild(fragment);
});// 3. 不使用文档片段直接添加元素到 DOM
document.getElementById(addBox).addEventListener(click, () {const container document.getElementById(container);const newBox document.createElement(div);newBox.className box new-style;container.appendChild(newBox); // 直接添加元素到 DOMconst newBox2 document.createElement(div);newBox2.className box new-style;container.appendChild(newBox2); // 直接添加元素到 DOMconst newBox3 document.createElement(div);newBox3.className box new-style;container.appendChild(newBox3); // 直接添加元素到 DOM
});脱离文档流对于一些大型操作使用绝对定位或固定定位可以将元素脱离文档流从而减少回流的影响。
// 4. 不脱离文档流使用默认的文档流布局
const floatingBox document.createElement(div);
floatingBox.className box;
floatingBox.style.top 150px; // 位置
floatingBox.style.left 150px; // 位置
document.body.appendChild(floatingBox); // 直接添加到文档中不脱离文档流 // 4. 脱离文档流使用绝对定位可减少回流影响
const floatingBox document.createElement(div);
floatingBox.className box;
floatingBox.style.position absolute; // 脱离文档流
floatingBox.style.top 150px; // 位置
floatingBox.style.left 150px; // 位置
document.body.appendChild(floatingBox); // 直接添加到文档中