前端知识速记:重绘和回流
前端知识速记:重绘和回流
一、什么是重绘与回流
1. 重绘(Repaint)
重绘是指当元素的外观发生变化时,浏览器需要重新绘制这些元素。由于这些操作不会改变元素占据的空间,因此不需要进行回流。常见的重绘操作包括:
- 元素的颜色、背景色、边框等样式属性发生变化
- 元素的可见性发生变化(如
display: none变为display: blockps:针对这个例子也会触发回流,并且是先触发回流,再触发重绘)- 回流(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 集合…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...
[USACO23FEB] Bakery S
题目描述 Bessie 开了一家面包店! 在她的面包店里,Bessie 有一个烤箱,可以在 t C t_C tC 的时间内生产一块饼干或在 t M t_M tM 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC,tM≤109)。由于空间…...
从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...
