前端性能优化-回流与重绘

news2024/9/21 10:40:35

前言

本文总结回流与重绘相关的知识点

回流与重绘的基本概念

重绘(Repaint): 当元素样式发生改变,但不影响其几何属性的时候,浏览器只需要重新绘制这个元素,这个过程被称为重绘。

回流(Reflow): 当页面布局和几何属性发生变化,导致部分或全部元素的尺寸、位置、结构发生改变时,浏览器需要重新计算元素的几何属性和页面的布局,这个过程被称为回流。

重绘不一定会触发回流,回流一定会触发重绘。

触发条件

回流和重绘的触发条件主要包括对 DOM 结构和样式的修改。以下是触发回流和重绘的常见操作:

回流的触发条件:

  • 初始化页面。
  • 改变窗口大小。
  • 添加、删除、更新 DOM 元素。
  • 改变元素的位置、尺寸、内容。
  • 修改元素的 font、padding、margin 等样式属性。

对于回流与重绘,我们可以直观地通过 chrome 的开发者工具来查看:

比如下面的 js 操作

document.querySelector(".box").addEventListener("click", function () {
  // 改变元素尺寸
  this.style.width = "200px";
});

通过 chrome 控制面板可以看到:

完整的 demo 请看👉 在线效果预览, 查看示例代码请点击此处

网上有说法: 获取 offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth.
scrollHeight、clientTop、clientLeft、clientWidth、clientHeight 以及调用 getComputedStyle 等属性和方法都会触发回流。
但是从 chrome 控制面板中看到这些现象并不会触发回流,所以这些说法有待商榷。

重绘的触发条件:

  • 修改元素的颜色、背景色。
  • 修改元素的 visibility、outline、box-shadow 等不影响布局的属性。

比如下面的 js 操作

document.querySelector(".box").addEventListener("click", function () {
  // 修改元素颜色
  this.style.backgroundColor = "red";
});

完整的 demo 请看👉 在线效果预览, 查看示例代码请点击此处

仔细与上图对比我们可以发现少了Layout 这一步,说明只触发了重绘,没有触发回流。

优化策略与最佳实践

合并多次修改

合并多次 DOM 和样式修改的优势,减少回流和重绘的次数。

// 不优化的写法,会触发多次回流和重绘
element.style.width = "100px";
element.style.height = "100px";
element.style.backgroundColor = "red";

// 优化的写法,合并为一次回流和重绘
element.style.cssText = "width: 100px; height: 100px; background-color: red;";

使用 class 操作

通过修改元素的类而不是直接操作样式,可以利用浏览器对类的处理进行优化。这样可以减少直接样式修改导致的回流和重绘。

// 不优化的写法,会触发回流和重绘
element.style.width = "100px";
element.style.height = "100px";
element.style.backgroundColor = "red";

// 优化的写法,通过修改类名实现
element.classList.add("custom-style");
/* CSS中定义样式 */
.custom-style {
  width: 100px;
  height: 100px;
  background-color: red;
}

离线操作

执行离线 DOM 操作,即在修改大量 DOM 元素之前,先将它们从文档中移除,进行操作后再放回文档。这样可以最小化对页面渲染的直接影响,降低回流和重绘的次数。

// 不优化的写法,会触发多次回流和重绘
for (let i = 0; i < 100; i++) {
  document.body.appendChild(document.createElement("div"));
}

// 优化的写法,离线操作
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const div = document.createElement("div");
  fragment.appendChild(div);
}
document.body.appendChild(fragment);

浏览器中的 Flush 队列

在浏览器的渲染引擎中,当发生 DOM 或样式变化时,引擎并不会立即执行相应的回流和重绘操作。相反,它将这些操作放入一个队列中,这个队列被称为 Flush 队列

具体的合并机制可以归结为以下几点:

  • 批量执行: 浏览器会等待一定时间,收集多个回流和重绘任务,然后一次性执行它们。这样可以减少任务的切换开销,并优化性能。
  • 策略性合并: 浏览器会根据一些策略性的考虑,将一些相关联的回流和重绘任务合并在一起。例如,如果某个元素的多个样式同时发生变化,浏览器可能会将它们合并成一个操作,以减少回流和重绘的次数。
  • 异步执行: 部分回流和重绘任务可能会被推迟到下一个事件循环(Event Loop)中执行。这意味着在当前事件循环中发生的多个 DOM 和样式变化可能会在下一个事件循环中被合并执行,从而减少了当前事件循环中的任务执行开销。

以下面一段 js 代码为例

const box = document.querySelector(".box");

box.addEventListener("click", () => {
  // 多次修改样式,合并为一次回流和重绘
  function performMultipleChanges() {
    box.style.width = "200px";
    box.style.height = "200px";
    box.style.backgroundColor = "red";
  }

  // 调用多次修改,观察合并效果
  performMultipleChanges();
  performMultipleChanges();
  performMultipleChanges();
});

执行效果如下图所示,可以看到chrome对上述的多个style变更以及多次的performMultipleChanges函数调用进行了合并,最终只触发了一次回流和重绘。

值得注意的是,并不是所有的浏览器都做了这些优化的操作,因此作为开发者,还是要提高自己的知识储备,尽量避免不必要的回流和重绘。

本文首发于个人博客前端开发笔记,由于笔者能力有限,文章难免有疏漏之处,欢迎指正

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

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

相关文章

Linux_监测CPU和内存

通过TOP持续获取进程的CPU和内存消耗&#xff0c;并写入到表格 # 配置进程名 processvm-agent # 配置次数 number100 # 配置间隔时间 time5 # csv结果文件 filecm_$(date %s).csv echo "%CPU,%MEM">${file} pid$(ps -aux | grep ${process} | awk -F {OFS"…

debug\moc\mocinclude.tmp dose not exist

先把jom禁用&#xff0c;然后清理工程&#xff0c;重新编译&#xff0c;编译通过后再重新打开jom

MybatisPlus的主键策略

ASSIGN_ID(默认策略) 生成唯一的值&#xff0c;包含数字&#xff0c;表对应字段类型bigint或者varchar类型 ASSIGN_UUID() 生成唯一的值&#xff0c;包含数字和字母&#xff0c;表对应字段类型varchar类型 AUTO 主键自动增长效果&#xff0c;和表字段auto_increment INPUT …

养猫劝退?猫咪浮毛太多难清理?宠物空气净化器一招搞定

受不了了&#xff0c;真的很想把家里的猫孩子丢出去&#xff01;平日实在是太能掉毛了&#xff0c;赶上换毛季更夸张&#xff0c;家里都要被猫毛淹没了。这些还能靠多加打扫卫生清理掉&#xff0c;可空气中的浮毛真是束手无策。对于我这种过敏性鼻炎患者&#xff0c;一旦空气中…

FSRCNN论文读后感

本文的主要目的是在尽可能保持恢复质量不变的情况下&#xff0c;提高模型的处理速度&#xff0c;以将其投入实际应用。&#xff08;注意&#xff1a;本文只要是针对大尺寸图像&#xff0c;但实验结果证明&#xff0c;FRSNN模型对于小尺寸图像的处理速度也比SRCNN快&#xff0c;…

鸿蒙应用开发之GridRow和GridCol容器

在不同屏幕上布局是一个比较困难的问题,因为屏幕大小不一样,导致内容布局会比较混乱。所以提出一种网络的方式来布局,即使屏幕大小改变了,但是布局行列数不变,那么内容就不会混乱。使用组件GridRow来管理行,使用组件GridCol管理列。 先来看一下组件GridRow的定义: Grid…

VSCode在windows系统下使用conda虚拟环境配置

如何解决CondaError: Run ‘conda init‘ before ‘conda activate‘_condaerror: run conda init before conda activat-CSDN博客 首先检查自己的anaconda是否是添加到整个的环境变量里了 打开cmd如果conda和python都能够识别那么就是配置成功了 然后看插件是否安装&#xf…

在 cPanel 和 WHM 中配置域名重定向

在处理HTTP请求时&#xff0c;服务器会返回页面内容&#xff0c;这一过程依赖于域名和IP地址的正确配置。手动配置IP和域名非常复杂&#xff0c;但cPanel & WHM的网页界面让日常的网络服务器管理变得轻而易举。例如&#xff0c;Hostease提供的服务器解决方案&#xff0c;支…

3DCoat v2023 激活版下载与安装教程 (数字雕刻程序)

前言 3DCoat 是一款数字雕塑软件&#xff0c;由乌克兰开发。该软件专注于游戏模型的细节设计&#xff0c;集三维模型实时纹理绘制和细节雕刻功能为一身&#xff0c;可以加速细节设计流程&#xff0c;在更短的时间内创造出更多的内容。 一、下载地址 下载链接&#xff1a;分享…

想实现ubuntu搭建sqli-labs靶场

目录 首先前期的nginx和php部署完成​编辑​编辑 Xftp导入sqli-labs 遇到了的问题 它提示我们请检查db-creds.inc 去尝试解决这个问题 尝试修改MySQL root密码 修改db-creds.inc配置 再次尝试依旧失败 思考&#xff1a;会不会是MySQL版本过高的原因 重新下载MySQL5.7.…

优思学院|精益管理的指导思想给企业带来了什么启示?

很多企业和管理者以为&#xff0c;多即是好&#xff0c;尽量加快生产&#xff0c;提升库存&#xff0c;库存越多&#xff0c;安全性越高&#xff0c;尽量迫使员工多做工作&#xff0c;他们的工作越多&#xff0c;效率就越高&#xff0c;凡此种种都是在精益思想诞生前的人们对营…

B站宋红康JAVA基础视频教程个人笔记chapter04

文章目录 1.IDEA安装好后的一些设置和学习1.1关于IDEA内部jdk版本的设置1.2 一些样式以及快捷键的常用设置&#xff08;强烈推荐&#xff09; 2.工程与模块管理3.如何彻底的卸载IDEA 1.IDEA安装好后的一些设置和学习 1.1关于IDEA内部jdk版本的设置 1.File—>Project Struc…

Lumos学习王佩丰Excel第十讲:Sumif函数

一、Sumif函数语法 Sumif函数&#xff1a;用于对区域中符合指定的单个条件的值求和。 sumif(range,criteria,[sum_range]) sumif(条件区域,求和条件,求和区域) 二、Sumif函数计算数值区间 【注意】 1、当函数中两个区域相同时&#xff0c;可省略写后一个区域&#xff1b; …

Android开发 显示密码 输入时短暂显示字符

文章目录 Android开发 显示密码 输入时短暂显示字符1、设置和获取密码是否可见2、 设置系统权限3、实际修改的Settings的属性4、adb控制密码是否短暂可见 Android开发 显示密码 输入时短暂显示字符 Android UI 控件EditText为密码类型的字符串的控制显示。密码字符串默认可以短…

详解贪心算法

贪心算法&#xff08;Greedy Algorithm) 概述&#xff1a; 贪心算法是一种在求解最优化问题时采取的一种常用算法策略。贪心算法的基本思想是&#xff0c;每次选择当前情况下的局部最优解&#xff0c;并相信这个局部最优解能够导致全局最优解。贪心算法通过迭代的方式一步步地…

Linux学习第57天:Linux PWM驱动实验

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 本章的思维导图如下&#xff1a; 一、PWM驱动简析 1、设备树下的PWM控制节点 8 路 PWM 都属于 I.MX6ULL 的 AIPS-1 域&#xff0c;分为了两部分&#xff0c; PWM1~P…

Spring Boot 中使用 JSON Schema 来校验复杂JSON数据

JSON是我们编写API时候用于数据传递的常用格式&#xff0c;那么你是否知道JSON Schema呢&#xff1f; 在数据交换领域&#xff0c;JSON Schema 以其强大的标准化能力&#xff0c;为定义和规范 JSON 数据的结构与规则提供了有力支持。通过一系列精心设计的关键字&#xff0c;JS…

MySQL的安装数据库的简单操作

&#x1f48e;所属专栏&#xff1a; MySQL &#x1f48e;1. 数据库相关概念 数据库&#xff1a;存储数据的仓库&#xff0c;数据是有组织的进行存储 数据库管理系统&#xff1a;操纵和管理数据库的大型软件 SQL:操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型…

基于Session和Cookie的模拟登录实战

准备工作 安装好 requests 库&#xff0c; 并掌握基本用法 安装 Selenium 库&#xff0c; 并掌握基本用法 案例介绍 用到的网站&#xff1a; https://login2.scrape.center/ 用户名和密码&#xff1a; admin 点击登录 这个网站是基于传统的 MVC 模式开发的&#xff0c;比较…

DM 数据迁移工具

1.1.概述 DM 数据迁移工具 DM DTS 提供了主流大型数据库迁移到 DM、DM 到 DM、文件迁移到 DM 以及 DM 迁移到文件等功能。 得益于 DM 数据库对目前主流大型关系型数据库系统有着业界领先的兼容性&#xff0c;在存储层面、语法层面、接口层面和它们保持高度兼容&#xff0c;借…