JavaScript中的Repaint和Reflow用法详解
简介
当我们操作DOM元素时,浏览器会自动在内部计算其布局和几何属性,这被称为回流(reflow)。同时,当我们对样式进行更改时,浏览器会重新渲染(repaint)发生更改的部分。这样做会提高应用程序或网站的性能,因为回流和重绘是比较昂贵的操作。
Repaint
在计算机图形中,当一个对象的视觉外观发生变化时,我们把这个过程叫做重新绘制(repaint)。repaint对于浏览器而言是一项相对轻松的操作,因为它仅仅是在已有的位置重新绘制元素内容,而不会影响页面的布局。
例如,当我们更改样式,如更改颜色时,这不会影响元素的布局,而仅仅是绘制同一元素的外观。如果仅仅需要改变元素的样式属性,应该使用Repaint而不是Reflow。
以下是使用JavaScript触发repaint的两种方法:
方法1:更改元素CSS中的伪类
这里我们使用:hover伪类来进行举例。当使用伪类来控制元素的样式时,它只会触发Repaint而不是Reflow。例如:
element:hover{
color: red;
}
方法2:使用JS方法来改变元素的样式
修改CSS会触发Repaint。使用此方法时,使用JS来暴露和改变元素的style属性,触发Repaint。下面是一个例子:
element.style.color = "red";
Reflow
在页面渲染过程中,浏览器会根据布局计算元素的几何属性和位置,这个计算过程称之为回流(reflow)。如果元素的位置或尺寸等几何属性发生改变,浏览器必须重置这个元素的样式,包括其他元素的样式也可能会受到影响,以保证正确的渲染。
reflow是一项昂贵的操作,因为它涉及大量的运算。如果需要更改页面的几何属性,请尽可能地减少reflow的次数。
以下是用于JS触发回流的常见代码:
方法1:改变或获取元素的几何属性
当改变元素的几何属性时,浏览器需要重新计算其他元素的位置和尺寸,以及更新页面的布局。当我们使用以下代码时,会发生Reflow:
element.offsetLeft;
element.offsetTop;
element.offsetWidth;
element.offsetHeight;
element.clientWidth;
element.clientHeight;
方法2:操作节点
当一个节点的位置发生变化时,DOM要重新计算节点位置并更新布局:
element.style.height = "100px";
示例1
下面是一个可以通过节流和防抖技术(即缓解回流的方法)来执行多次代码的例子:
function handleScroll() {
// 引导页的初始高度在样式中定义为2000px
const GUIDE_HEIGHT = 2000;
const scrollTop = document.documentElement.scrollTop;
// 获取指向首页按钮的元素
const homeButton = document.getElementById('home-button');
// 如果垂直滚动距离大于引导页面的高度
if (scrollTop > GUIDE_HEIGHT) {
// 在按钮上设置新的样式
homeButton.style.opacity = '1';
} else {
// 如果在引导页面内
homeButton.style.opacity = '0';
}
}
// 用于检测页面滚动,防止过度重绘和回流
window.onscroll = throttle(() => {
handleScroll();
}, 50);
在这个例子中,我们设置了一个事件处理程序用来处理页面滚动的事件,同时使用防抖(throttle)技术使页面滚动事件的回流和重绘的次数降到最低。
示例2
下面是另一个使用缓解连续回流的例子:
const searchInput = document.getElementById('search-input');
const searchResult = document.getElementById('search-results');
function search() {
// 获取搜索关键词
const keyword = searchInput.value.toLowerCase();
// 准备用于搜索的结果
let results = '';
// 在搜索结果中查找包含关键词的结果
for (let i = 0; i < data.length; i++) {
if (data[i].toLowerCase().includes(keyword)) {
results += `<li>${data[i]}</li>`;
}
}
// 向DOM添加新的html代码
searchResult.innerHTML = results;
}
// 使用操作输入的防抖函数
searchInput.addEventListener('input', debounce(search, 250));
在搜索输入框中键入关键词后,页面会实时更新搜索结果,该功能易导致连续回流。这时可以采用使用防抖来控制触发搜索的频率,从而减少回流和重绘的次数。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript中的Repaint和Reflow用法详解 - Python技术站