怎么理解回流和重绘?

回流(reflow)和 重绘(repaint)是浏览器渲染过程中的两个关键概念。

一、概念:

  • 回流指的是浏览器在计算文档流布局(layout)时,重新计算元素的位置和大小的过程。当页面中的元素发生尺寸变化、添加或删除元素、文本内容变化等操作时,会触发回流。回流可能会导致其他元素的位置和大小也需要重新计算,这可能是一个比较耗费性能的操作。
  • 重绘是指在回流之后,浏览器将更新后的元素样式绘制到屏幕上的过程。当元素的外观属性(如颜色、背景等)发生变化时,会触发重绘。重绘不涉及布局的计算,所以性能上相对来说较回流开销较小。

具体的浏览器解析渲染机制如下所示:

在这里插入图片描述

  • 解析HTML,生成DOM树,解析CSS,生成CSSOM树

  • 将DOM树和CSSOM树结合,生成渲染树(Render Tree)

  • Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)

  • Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素

  • Display:将像素发送给GPU,展示在页面上

在页面初始渲染阶段,回流不可避免的触发,可以理解成页面一开始是空白的元素,后面添加了新的元素使页面布局发生改变;

当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性,然后再将计算的结果绘制出来;

当我们对 DOM 的修改导致了样式的变化(color或background-color),却并未影响其几何属性时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式,这里就仅仅触发了重绘。

二、示例:

当涉及到回流和重绘时,以下是一些常见的例子:

  1. 修改元素的尺寸:例如,通过 JavaScript 动态修改元素的宽度或高度。这会触发回流,因为浏览器需要重新计算元素的布局,并随后进行重绘。
// 触发回流和重绘
element.style.width = "200px";
element.style.height = "100px";
  1. 改变字体属性:如果在 CSS 中改变了元素的字体大小、字体样式等属性,将会触发回流和重绘。因为文本的尺寸变化可能会导致周围元素的位置和大小发生变化。
/* 触发回流和重绘 */
.element {
  font-size: 16px;
  font-weight: bold;
}
  1. 添加或删除元素:当通过 JavaScript 动态添加或删除元素时,会触发回流和重绘。因为浏览器需要重新计算文档流的布局,并更新显示。
// 触发回流和重绘
var newElement = document.createElement("div");
parentElement.appendChild(newElement);

// 触发回流和重绘
var elementToRemove = document.getElementById("elementId");
parentElement.removeChild(elementToRemove);
  1. 修改元素的位置:如果通过修改元素的定位属性(如 top、left)来改变其位置,会触发回流和重绘。因为周围元素的布局可能会受到影响。
// 触发回流和重绘
element.style.position = "absolute";
element.style.top = "50px";
element.style.left = "100px";
  1. 改变元素的背景色或边框样式:当通过 CSS 修改元素的背景色、边框样式等外观属性时,将触发重绘。这不会引起回流,因为这些属性的更改不会影响布局。
/* 触发重绘,不触发回流 */
.element {
  background-color: red;
  border: 1px solid black;
}

需要注意的是,不同浏览器对回流和重绘的处理方式可能略有差异。此外,现代浏览器通常会对频繁的回流进行优化,尽量减少性能开销。然而,过多的回流和重绘仍然可能导致页面性能下降,因此在编写代码时应尽量避免不必要的操作。

三、理解回流和重绘的关系可以简单如下:

  1. 回流必然伴随着重绘:当元素的位置和大小发生改变时,不仅需要进行回流计算,还需要进行重绘操作。所以每次回流都会导致重绘。

  2. 重绘不一定会引起回流:当元素的外观属性发生改变时,只需要进行重绘而无需重新计算布局,因此不一定会引起回流。比如改变了元素的颜色、背景等样式属性。

由于回流涉及到布局的计算,因此它的性能开销较大,会导致页面重新渲染,影响用户体验和页面性能。所以在开发过程中应尽量避免频繁的回流操作,可以采取以下措施:

  • 批量修改样式:将多个样式的修改集中到一起,通过添加或移除 CSS 类来实现样式的批量更改,减少回流次数。
  • 避免强制同步布局:典型的例子是查询某些布局属性(如 offsetTop、offsetWidth 等)时,浏览器会强制进行回流以保证获取到最新的值。如果无法避免,可以尽量减少这类操作的次数。
  • 使用 transform 替代 top/left:使用 CSS3 的 transform 属性进行位移操作,能够避免回流,并有较好的性能表现。

总之,了解回流和重绘的原理能够帮助我们优化代码,减少不必要的性能开销,提升页面的渲染性能。

四、下面是减少回流和重绘的方法的一些优点和缺点:

优点:

  1. 提高页面性能:减少回流和重绘可以减少浏览器的计算和渲染工作量,从而提高页面的性能和响应速度。
  2. 减少资源消耗:回流和重绘会消耗 CPU 和 GPU 资源,通过减少它们的次数,可以降低系统资源的使用,延长电池寿命等。
  3. 改善用户体验:减少回流和重绘可以减少页面加载和渲染的延迟,提高用户与网页的交互体验。

缺点:

  1. 可能增加代码复杂性:为了减少回流和重绘,可能需要对代码进行修改,引入额外的逻辑,从而增加代码的复杂性和维护成本。
  2. 可能影响开发效率:在追求性能最佳实践的同时,可能需要投入更多的时间和精力来进行代码优化和测试。
  3. 不适用于所有情况:有时候,为了实现特定的功能或效果,可能无法完全避免回流和重绘。在这种情况下,需要权衡性能和功能之间的平衡。

综上所述,减少回流和重绘可以有效提高页面性能和用户体验,但需要权衡代码复杂性和开发效率。在实际开发中,需要根据具体情况做出决策,选择适合的优化方法。

五、如何减少回流和重绘呢?

  1. 批量修改样式:尽量避免多次修改单个元素的样式,而是通过添加或移除 CSS 类来一次性修改多个样式。这样可以限制回流和重绘的次数。
// 不推荐的方式(多次回流和重绘)
element.style.width = "200px";
element.style.height = "100px";

// 推荐的方式(一次回流和重绘)
element.classList.add("new-styles");
  1. 使用 transform 替代定位属性:在改变元素的位置时,使用 transform 属性代替 top/left 属性。因为 transform 属性只会触发重绘,而不会触发回流。
// 不推荐的方式(触发回流和重绘)
element.style.position = "absolute";
element.style.top = "50px";
element.style.left = "100px";

// 推荐的方式(只触发重绘)
element.style.transform = "translate(100px, 50px)";
  1. 缓存布局信息:如果需要多次读取元素的布局属性(如宽度、高度),最好先将这些属性值缓存起来,以免重复触发回流。
// 不推荐的方式(重复触发回流)
var width = element.offsetWidth;
console.log(width);
var height = element.offsetHeight;
console.log(height);

// 推荐的方式(缓存布局属性值)
var width = element.offsetWidth;
var height = element.offsetHeight;
console.log(width, height);
  1. 使用分离的 DOM 批处理:如果需要多次对 DOM 进行修改,可以将这些修改操作集中在一起,然后再将它们插入到文档中。这样可以减少回流和重绘的次数。
// 不推荐的方式(多次回流和重绘)
for (var i = 0; i < 100; i++) {
  var newElement = document.createElement("div");
  parentElement.appendChild(newElement);
}

// 推荐的方式(批量插入元素,减少回流和重绘)
var fragment = document.createDocumentFragment();
for (var i = 0; i < 100; i++) {
  var newElement = document.createElement("div");
  fragment.appendChild(newElement);
}
parentElement.appendChild(fragment);

通过采用上述方法,可以最大程度地减少回流和重绘的次数,提高页面的性能和响应速度,提高页面性能和用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/215101.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

spring boot 事件机制

目录 概述实践监听spring boot ready事件代码 源码初始化流程调用流程 结束 概述 spring boot 版本为 2.7.17 。 整体看一下spring及spring boot 相关事件。 根据下文所给的源码关键处&#xff0c;打上断点&#xff0c;可以进行快速调试。降低源码阅读难度。 实践 spring…

传媒行业CRM:打造高效客户管理,提升品牌影响力

传媒行业充满竞争和变化&#xff0c;传媒企业面临着客户管理不透明、业务流程混乱、销售数据分析不足&#xff0c;无法优化营销策略和运营管理等问题。CRM系统是企业实现数智化管理的神器&#xff0c;可以有效解决这些问题。下面说说&#xff0c;传媒行业CRM系统推荐。 1、建立…

webGL开发VR和AR应用

开发 WebVR&#xff08;虚拟现实&#xff09;和 WebAR&#xff08;增强现实&#xff09; 应用需要使用 WebXR 技术&#xff0c;结合 WebGL 以实现高质量的图形渲染。以下是开发这类应用的一般技术方案&#xff0c;希望对大家有所帮助。 1.WebXR API: 使用 WebXR API&#xff0…

基于Java SSM框架+Vue实现企业公寓后勤管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架Vue实现企业宿舍后勤管理网站演示 摘要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所…

陪玩圈子系统:打破单身孤独,展开精彩社交旅程,APP小程序H5,源码交付,支持二开!

近年来&#xff0c;随着社交网络的快速发展&#xff0c;越来越多的人开始寻求各种方式来解决单身孤独的问题。而陪玩圈子系统便应运而生&#xff0c;在为用户提供社交服务的同时也促进了人与人之间的互动和交流。在这个拥有庞大用户数量和各种丰富活动的平台上&#xff0c;你将…

【LeetCode】每日一题 2023_12_4 从二叉搜索树到更大和树(二叉树)

文章目录 刷题前唠嗑题目&#xff1a;从二叉搜索树到更大和树题目描述代码与解题思路 结语 刷题前唠嗑 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 题目&#xff1a;从二叉搜索树到更大和树 题目链接&#xff1a;1038. 从二叉搜索树到更大和树 题目描述…

HarmonyOS4.0之安装DevEco Studio开发工具

第一步 打开网址&#xff1a;https://developer.huawei.com/consumer/cn/ 点击后是这样的界面 第二步 鼠标移入到开发点击DevEco Studio 第三步 我们往下滑动找到以下界面 我们根据自己的需要点击下载图标 这里演示Window系统 下载好后解压文件 我们解压文件后 第四步…

如何批量修改ppt中的字体?

ppt制作已经属于是复杂的操作了&#xff0c;当我们想要更换ppt中的字体&#xff0c;有没有什么快捷的方法呢&#xff1f;今天分享两个方法&#xff0c;一键修改ppt文件字体。 方法一&#xff1a; 找到功能栏中的编辑选项卡&#xff0c;点击替换 – 替换字体&#xff0c;在里面…

面试题:为什么数据库连接池不采用 IO 多路复用?

今天我们聊一个不常见的 Java 面试题&#xff1a;为什么数据库连接池不采用 IO 多路复用&#xff1f; 这是一个非常好的问题。IO多路复用被视为是非常好的性能助力器。但是一般我们在使用 DB 时&#xff0c;还是经常性采用c3p0&#xff0c;tomcat connection pool等技术来与 D…

C++基础 -37- 模板函数与普通函数调用规则

当模板函数比普通函数更好匹配形参的时候&#xff0c;会优先调用模板函数 #include "iostream"using namespace std;template <class T> void show(T a, T b) {cout << a << endl;cout << b << endl;cout << "temp show&…

MQ - KAFKA 高级篇

kafak是一个分布式流处理平台,提供消息持久化,基于发布-订阅的方式的消息中间件&#xff0c;同时通过消费端配置相同的groupId支持点对点通信。 ##适用场景&#xff1a; 构造实时流数据管道,用于系统或应用之间可靠的消息传输.数据采集及处理,例如连接到一个数据库系统,捕捉表…

Redis--15--缓存穿透 击穿 雪崩

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 缓存穿透 击穿 雪崩运行速度:1 缓存穿透问题描述:如何解决: 2 缓存击穿问题描述:如何解决: 3 缓存雪崩说明:解决方案: 缓存穿透 击穿 雪崩 问题描述: 由于海量的用…

漂亮极了!分享我收藏的 16 款 VS Code 主题

你好&#xff0c;我是 EarlGrey&#xff0c;喜欢翻译点东西&#xff0c;偶尔写写代码。 点击下方卡片关注我&#xff0c;一起向上进击&#xff0c;提升自我。后台回复关键词“电子书”&#xff0c;送你一份我收藏的电子书合集。 Visual Studio Code&#xff08;VS Code&#xf…

VMware安装OpenEuler(安装界面)

本文中使用的OpenEuler版本&#xff1a;22.03 LTS SP2 VMware&#xff1a;17.0.0 一、下载镜像 根据CPU和场景&#xff0c;按需下载 https://www.openeuler.org/zh/download/?versionopenEuler%2022.03%20LTS%20SP2 二、初始化VmWare 三、配置操作系统 四、安装操作系统 …

Python:核心知识点整理大全1-笔记

在本章中&#xff0c;你将运行自己的第一个程序——hello_ world.py。为 此&#xff0c;你首先需要检查自己的计算机是否安装了Python&#xff1b;如果没有安装&#xff0c; 你需要安装它。你还要安装一个文本编辑器&#xff0c;用于编写和运行Python 程序。你输入Python代码时…

【GD32307E-START】04 使用TinyMaix进行手写数字识别

【GD32307E-START】04 使用TinyMaix进行手写数字识别 参考博客 【GD32F427开发板试用】使用TinyMaix进行手写数字识别 https://blog.csdn.net/weixin_47569031/article/details/129009839 软硬件平台 GD32F307E-START Board开发板GCC Makefile TinyMaix简介 TinyMaix是国…

从马帮到金蝶云星空通过接口配置打通数据

从马帮到金蝶云星空通过接口配置打通数据 接入系统&#xff1a;马帮 上海马帮科技有限公司&#xff0c;是一家专注于提供全流程跨境电商ERP管理软件解决方案的企业。聚焦服务于各阶段、各领域的跨境电商从业者&#xff0c;旗下包含专业版ERP、亚马逊专用版ERP、东南亚海外版ERP…

SimCSE论文阅读

正负样本对构建原理正样本pair&#xff1a;one sentence two different embeddings as “positive pairs”. (通过dropout 作为噪声)负样本pair&#xff1a;Then we take other sentences in the same mini-batch as “negatives”任务&#xff1a; the model predicts the pos…

cup型号的意思

CPU 在整个计算机硬件中、技术体系中都算是最最重要的东西了。在 10 月 16 号的时候&#xff0c;Intel 正式发布了第 14 代的酷睿处理器。 一、Intel 的 CPU 型号规则 无论是哪家 CPU 厂商&#xff0c;为了更好地管理自己生产的众多型号的产品&#xff0c;也为了能更好地让消…

学生使用台灯到底好不好?学生备考台灯分享

普通台灯的出现只是为了照明&#xff0c;且它的功能也就只有照明&#xff0c;像是眩光、蓝光、频闪、过亮过暗等等都是普通台灯所存在的问题&#xff0c;而这些问题也正是造成我们眼睛近视、诱发眼部疾病的罪魁祸首&#xff0c;特别是正处于发育时期的青少年们&#xff0c;抵抗…