前端知识速记:重绘和回流
前端知识速记:重绘和回流
一、什么是重绘与回流
1. 重绘(Repaint)
重绘是指当元素的外观发生变化时,浏览器需要重新绘制这些元素。由于这些操作不会改变元素占据的空间,因此不需要进行回流。常见的重绘操作包括:
- 元素的颜色、背景色、边框等样式属性发生变化
- 元素的可见性发生变化(如
display: none
变为display: block
ps:针对这个例子也会触发回流,并且是先触发回流,再触发重绘)- 回流(Reflow) :
display: none
的元素不会在页面中占据空间,也不会参与布局计算。当将其改为display: block
时,元素会重新出现在页面中并占据空间,这使得浏览器需要重新计算该元素以及可能受其影响的其他元素的布局信息,确定它们在页面上的位置和大小,这个重新计算布局的过程就是回流。 - 重绘(Repaint) :在完成回流,确定好元素新的布局信息后,浏览器需要根据新的样式和布局将元素绘制到屏幕上,更新元素的外观,这个过程就是重绘。
- 回流(Reflow) :
感谢 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); // 直接添加到文档中
相关文章:
前端知识速记:重绘和回流
前端知识速记:重绘和回流 一、什么是重绘与回流 1. 重绘(Repaint) 重绘是指当元素的外观发生变化时,浏览器需要重新绘制这些元素。由于这些操作不会改变元素占据的空间,因此不需要进行回流。常见的重绘操作包括&…...
webrtc peerconnection_client peerconnection_server 连接失败问题解决 win10 win11
0 常见问题 (1) webrtc peerconnection_client 连接 peerconnection_server 无连接列表 (2)连接导致崩溃debug状态下因为这个断言 RTC_DCHECK_RUN_ON(&capture_checker_); 1 在 peerconnection\client\main.cc 当中 定义类 class CustomSock…...

【C++】STL——list的使用与底层实现
目录 💕1.带头双向链表List 💕2.list用法介绍 💕3.list的初始化 💕4.size函数与resize函数 💕5.empty函数 💕6.front函数与back函数 💕7.push_front,push_back,pop_front,pop_back函数…...

iOS 音频录制、播放与格式转换
iOS 音频录制、播放与格式转换:基于 AVFoundation 和 FFmpegKit 的实现 在 iOS 开发中,音频处理是一个非常常见的需求,比如录音、播放音频、音频格式转换等。本文将详细解读一段基于 AVFoundation 和 FFmpegKit 的代码,展示如何实现音频录制、播放以及 PCM 和 AAC 格式之间…...
【PyTorch】解决Boolean value of Tensor with more than one value is ambiguous报错
理解并避免 PyTorch 中的 “Boolean value of Tensor with more than one value is ambiguous” 错误 在深度学习和数据科学领域,PyTorch 是一个强大的工具,它允许我们以直观和灵活的方式处理张量(Tensor)。然而,即使…...
Jsoup库具体怎么用?
Jsoup 是一个非常强大的 Java 库,用于解析和操作 HTML 文档。它提供了丰富的功能,包括发送 HTTP 请求、解析 HTML 内容、提取数据、修改 HTML 元素等。以下将详细介绍 Jsoup 的基本用法和一些高级功能,帮助你更好地使用 Jsoup 进行网络爬虫开…...
python:如何播放 .spx 声音文件
.spx 是 Speex音频编解码器的文件扩展名,它是一种开源的、免费的音频编解码器,主要用于语音压缩和语音通信领域。spx 文件通常用于语音记录、VoIP应用、语音信箱等场景。 .mp3 是一种广泛使用的音频格式,它采用了有损压缩算法,可…...
HTML学习笔记(6)
利用dom操作实现,对一个表格的增删改查 代码如下: todolist.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, …...

走向基于大语言模型的新一代推荐系统:综述与展望
HightLight 论文题目:Towards Next-Generation LLM-based Recommender Systems: A Survey and Beyond作者机构:吉林大学、香港理工大学、悉尼科技大学、Meta AI论文地址: https://arxiv.org/abs/2410.1974 基于大语言模型的下一代推荐系统&…...

【DeepSeek-R1 +1.5B】2060显卡ollama本地部署+open-webui界面使用
https://github.com/open-webui/open-webui Deepseek开源R1系列模型,纯RL助力推理能力大跃升! 2060显卡下使用deepseek-r1-1.5B deepseek开源小模型需要的显存(根据显存来选模型大小) ,图from: DeepSeek本地部署&…...
《翻转组件库之发布》
背景 继《翻转组件库之打包》_杨晓风-linda的博客-CSDN博客之后,组件库已经可以正常构建,那如何像elementUI等组件库那样,用npm安装,按照既定的用法使用即可呢?本篇便为你揭晓 资料相关 1、npm官方文档:…...
在深度学习中,样本不均衡问题是一个常见的挑战,尤其是在你的老虎机任务中,某些的中奖倍数较高
在深度学习中,样本不均衡问题是一个常见的挑战,尤其是在你的老虎机任务中,某些的中奖倍数较高 在深度学习中,样本不均衡问题是一个常见的挑战,尤其是在你的老虎机任务中,某些的中奖倍数较高而其他的中奖倍数较低。这种不均衡会导致模型偏向于高频样本(低中奖倍数的),…...

语言月赛 202311【基因】题解(AC)
》》》点我查看「视频」详解》》》 [语言月赛 202311] 基因 题目描述 有一个长度为 n n n 的字符串 S S S。其只包含有大写字母。 小 A 将 S S S 进行翻转后,得到另一个字符串 S ′ S S′。两个字符串 S S S 与 S ′ S S′ 对应配对。例如说,对…...

unity学习26:用Input接口去监测: 鼠标,键盘,虚拟轴,虚拟按键
目录 1 用Input接口去监测:鼠标,键盘,虚拟轴,虚拟按键 2 鼠标 MouseButton 事件 2.1 鼠标的基本操作 2.2 测试代码 2.3 测试情况 3 键盘Key事件 3.1 键盘的枚举方式 3.2 测试代码同上 3.3 测试代码同上 3.4 测试结果 4…...

GB/T 43698-2024 《网络安全技术 软件供应链安全要求》标准解读
一、43698-2024标准图解 https://mmbiz.qpic.cn/sz_mmbiz_png/rwcfRwCticvgeBPR8TWIPywUP8nGp4IMFwwrxAHMZ9Enfp3wibNxnfichT5zs7rh2FxTZWMxz0je9TZSqQ0lNZ7lQ/640?wx_fmtpng&fromappmsg 标准在线预览: 国家标准|GB/T 43698-2024 相关标准: &a…...
ASP.NET Core与EF Core的集成
目录 分层项目中EF Core的用法 数据库的配置 数据库迁移 步骤汇总 注意: 批量注册上下文 分层项目中EF Core的用法 创建一个.NET类库项目BooksEFCore,放实体等类。NuGet:Microsoft.EntityFrameworkCore.RelationalBooksEFCore中增加实…...
【AI大模型】Ubuntu18.04安装deepseek-r1模型+服务器部署+内网访问
以下内容主要参考博文:DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」 - 程序设计实验室 - 博客园 安装 ollama Download Ollama on Linux curl -fsSL https://ollama.com/install.sh | sh 配置 ollama 监听地址 ollama 安装后…...

SpringAI系列 - 使用LangGPT编写高质量的Prompt
目录 一、LangGPT —— 人人都可编写高质量 Prompt二、快速上手2.1 诗人 三、Role 模板3.1 Role 模板3.2 Role 模板使用步骤3.3 更多例子 四、高级用法4.1 变量4.2 命令4.3 Reminder4.4 条件语句4.5 Json or Yaml 方便程序开发 一、LangGPT —— 人人都可编写高质量 Prompt La…...
Github - 记录一次对“不小心包含了密码的PR”的修复
Github - 记录一次对“不小心包含了密码的PR”的修复 前言 和好朋友一起开发一个字节跳动青训营抖音电商后端(now private)的项目,某大佬不小心把本地一密码commit上去并提了PR。 PR一旦发出则无法被删除,且其包含的commit也能被所有能看到这个仓库的…...

【玩转 Postman 接口测试与开发2_014】第11章:测试现成的 API 接口(下)——自动化接口测试脚本实战演练 + 测试集合共享
《API Testing and Development with Postman》最新第二版封面 文章目录 3 接口自动化测试实战3.1 测试环境的改造3.2 对列表查询接口的测试3.3 对查询单个实例的测试3.4 对新增接口的测试3.5 对修改接口的测试3.6 对删除接口的测试 4 测试集合的共享操作4.1 分享 Postman 集合…...
c#bitconverter操作,不同变量类型转byte数组
缘起:串口数据传输的基础是byte数组,write(buff,0,num)或者writeline(string),如果是字符串传输就是string变量就可以了,但是在modbus这类hex传递时,就要遇到转换了,拼凑byte数组时需要各种变量的值传递,解…...
Qt Test功能及架构
Qt Test 是 Qt 框架中的单元测试模块,在 Qt 6.0 中提供了全面的测试功能。 一、主要功能 核心功能 1. 单元测试框架 提供完整的单元测试基础设施 支持测试用例、测试套件的组织和执行 包含断言宏和测试结果收集 2. 测试类型支持 单元测试:对单个函…...
AI代码助手需求说明书架构
AI代码助手需求说明书架构 #mermaid-svg-6dtAzH7HjD5rehlu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6dtAzH7HjD5rehlu .error-icon{fill:#552222;}#mermaid-svg-6dtAzH7HjD5rehlu .error-text{fill:#552222;s…...

FastAPI安全异常处理:从401到422的奇妙冒险
title: FastAPI安全异常处理:从401到422的奇妙冒险 date: 2025/06/05 21:06:31 updated: 2025/06/05 21:06:31 author: cmdragon excerpt: FastAPI安全异常处理核心原理与实践包括认证失败的标准HTTP响应规范、令牌异常的特殊场景处理以及完整示例代码。HTTP状态码选择原则…...
SpringAI Alibaba实战文生图
1️⃣ 前置准备:搭建开发环境与服务配置🚀 🔧 1.1 环境要求 JDK 17(推荐 JDK 21)、Spring Boot 3.x(本案例使用 3.3.4)、阿里云百炼大模型服务 API Key。需在阿里云控制台完成服务开通并获取有…...

mysql 页的理解和实际分析
目录 页(Page)是 Innodb 存储引擎用于管理数据的最小磁盘单位B树的一般高度记录在页中的存储 innodb ibd文件innodb 页类型分析ibd文件查看数据表的行格式查看ibd文件 分析 ibd的第4个页:B-tree Node类型先分析File Header(38字节-描述页信息…...
el-tabs 切换时数据不更新的问题
最近业务需求,需要在页面中使用tabs,使用过程中出现tabs切换,数据不更新的问题,以下是思路和解决办法。 Vue 会追踪你在模板中绑定的数据,并在数据发生变化时重新渲染相应的部分。但在使用 el-tabs 时,有时…...

产品经理课程(九)
从需求到功能设计 (一)复习 产品规划:产品定位、阶段性计划 产品定位:产品画布(9个步骤;最重要的是先解决什么问题) (Roadmap)目标要素:时间、事项、里程碑…...

MVC分层架构模式深入剖析
🔄 MVC 交互流程 #mermaid-svg-5xGt0Ka13DviDk15 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5xGt0Ka13DviDk15 .error-icon{fill:#552222;}#mermaid-svg-5xGt0Ka13DviDk15 .error-text{fill:#552222…...

基于J2EE架构的在线考试系统设计与实现【源码+文档】
目录 摘要: Abstract: 1 引言 2 在线考试系统构架 2.1 在线考试系统一般需求分析 2.2 当前在线考试系统现状分析 2.3 基于J2EE的在线考试系统架构介绍及拥有的优势 2.3.1 结构总体介绍 2.3.2 客户层组件 2.3.2.1 Applets 2.3.2.2 应用程序客户端 2.3.3 …...