怎么理解回流和重绘?

回流(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);

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode—1038.从二叉搜索树到更大和树【中等】

2023每日刷题&#xff08;四十九&#xff09; Leetcode—1038.从二叉搜索树到更大和树 算法思想 二叉搜索树的中序遍历&#xff08;左根右&#xff09;结果是一个单调递增的有序序列&#xff0c;我们反序进行中序遍历&#xff08;右根左&#xff09;&#xff0c;即可以得到一…

网络层之SDN基本概念、路由算法和路由协议

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

自然语言处理:电脑如何理解我们的语言?

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 ​ 文章目录 ​编辑 常见方法 1.基于词典的方法 2.基于计数的方法 基于推理的方法 Bert input_ids attention_mask token_type_ids 结语 在广…

排序算法介绍(五)归并排序

0. 简介 归并排序&#xff08;Merge Sort&#xff09;是一种分治思想的应用&#xff0c;它将待排序的数组不断拆分成小数组&#xff0c;直到每个小数组只有一个元素&#xff0c;然后将小数组两两合并&#xff0c;直到最终得到有序的数组。 1. 归并排序的实现 归并排序的基本思…

【2021研电赛】基于EAIDK310的视觉导航自动驾驶小车

本作品介绍参与极术社区的有奖征集|分享研电赛作品扩大影响力&#xff0c;更有重磅电子产品免费领取! 团队价绍 参赛单位&#xff1a;上海应用技术大学 参赛队伍&#xff1a;EAIDK666 指导老师&#xff1a;蒋文萍 丁肇红 参赛队员&#xff1a;温晓静 孙亦劼 杜为栋 获奖情况&a…

JS防抖与节流

防抖 防抖是什么&#xff1f; 单位时间内&#xff0c;频繁触发事件&#xff0c;只执行最后一次 通俗易懂点就是把防抖想象成MOBA游戏的回城&#xff0c;在回城过程中被打断就要重来 例子&#xff1a;我们来做一个效果&#xff0c;我们鼠标在盒子上移动&#xff0c;数字就变化 …

Python爬虫:使用Scrapy框架进行高效爬取

Python爬虫可使用的架构有很多&#xff0c;对于我而言&#xff0c;经常使用Scrapy异步处理框架Twisted&#xff0c;其实意思很明确&#xff0c;Scrapy可以实现多并发处理任务&#xff0c;同一时间将可以处理多个请求并且大大提高工作效率。 Scrapy是一个强大且高效的Python爬虫…

鸿蒙Watch 页面跳转

新建页面 config.json 回自动注册 添加跳转 <button type"capsule" onclick"toStatusMonitor">状态检测</button>写跳转方法 import router from system.router;export default {data: {},onInit() {},onShow() {},toStatusMonitor() {rou…

深度学习——第3章 Python程序设计语言(3.2 Python程序流程控制)

无论是在机器学习还是深度学习中&#xff0c;Python已经成为主导性的编程语言。而且&#xff0c;现在许多主流的深度学习框架&#xff0c;例如PyTorch、TensorFlow也都是基于Python。本课程主要是围绕“理论实战”同时进行&#xff0c;所以本章将重点介绍深度学习中Python的必备…

pandas、numpy的几个示例

这里写自定义目录标题 Pandas 示例NumPy 示例数据分析案例: Iris 数据集 Pandas 示例 Pandas 是一个数据处理和分析的库&#xff0c;它提供了 DataFrame 和 Series 这两种主要数据结构。 # 从字典创建 DataFrame import pandas as pd# 创建一个字典 data {Name: [Alice, Bob…

C++学习之路(十七)C++ 用Qt5实现一个工具箱(增加托盘图标并且增加显示和退出菜单)- 示例代码拆分讲解

上篇文章&#xff0c;我们用 Qt5 实现了在小工具箱中添加了《为屏幕颜色提取功能增加一个点击复制的功能》功能。今天我们增加一个比较正式点的功能&#xff0c;就是增加托盘图标并且增加显示和退出菜单&#xff08;越来越像回事了吧 &#x1f601; &#xff09;。下面我们就来…

【CMD】关于在for中SET变量失效的问题

如题&#xff0c;在for中进行一些细化操作时发现SET变量一直不成功(尤其在读取文件时)   简单搜了下看到有个帖子(BAT求助与讨论-SET变量失效)是讨论这个问题的&#xff0c;然后有个老哥给出的解答&#xff0c;其中使用了使用CALL&#xff0c;这让我想起几天前看到的一个博客…

Linux4.7、环境变量

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 目录 基本概念 见见环境变量 指令原理 常见环境变量及其测试 环境变量相关指令 环境变量组织方式 通过代码获取环境变量 通过系统变量获取环境变量以及设置环境变量 环境变量的全局属性 基本概念 首先&#xff0c;…

什么?居然可以免费使用Jetbrains?!

JetBrains是一家捷克的软件开发公司&#xff0c;该公司位于捷克的布拉格&#xff0c;并在俄罗斯的圣彼得堡及美国麻州波士顿都设有办公室&#xff0c;该公司最为人所熟知的产品是Java编程语言开发撰写时所用的集成开发环境&#xff1a;IntelliJ IDEA。 如下是jetbrains旗下的产…

【笔记】Clion 中运行 C/C++11 之 CMakeLists.txt 的配置

该文章记录第一次使用 Clion 时&#xff0c;对 CMakeLists 的配置&#xff0c;使其能够运行 C/C11 的代码。 一. CMakeLists.txt 的配置 1、首先我们在需要新建一个项目 2、填写新建项目相关的信息 3、修改 CMakeLists.txt 文件内容 替换文本&#xff1a; # 使用此 CMakeLis…

帆软报表不能增加SAP连接方式 通过插件一致性检测 同步至本地解决

帆软报表开发人员需要增加一个SAP数据连接方式&#xff1a;SAP_ECC_600环境 在服务器端不能直接增加&#xff0c;而在帆软报表设计器切换到远程模式时&#xff0c;又不能显示SAP连接&#xff0c;导致不能增加。 解决&#xff1a;重新进入帆软报表报计器时报以下错误&#xff0c…

开源运维监控系统-Nightingale(夜莺)应用实践(未完)

一、前言 某业务系统因OS改造,原先的Zabbix监控系统推倒后未重建,本来计划用外部企业内其他监控系统接入,后又通知需要自建才能对接,考虑之前zabbix的一些不便,本次计划采用一个类Prometheus的监控系统,镜调研后发现Nightingale兼容Prometheus,又有一些其他功能增强,又…

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

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

JavaScript空值合并运算符

The Nullish Coalescing Operator&#xff08;空值合并运算符&#xff09;是一种 JavaScript 的新运算符&#xff0c;用于解决默认值设定中存在的一些问题。它的语法为 ??&#xff08;两个问号&#xff09;&#xff0c;表示当左侧的操作数为 null 或 undefined 时&#xff0c…

【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(1)spring boot项目搭建、vue项目搭建、微信小程序项目搭建

项目笔记为项目总结笔记,若有错误欢迎指出哟~ 【项目专栏】 【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(1)项目搭建 持续更新中… java+vue+微信小程序项目】从零开始搭建——健身房管理平台 项目简介Java项目搭建(IDEA)1.新建项目2.项目类型3.项目设置4…