当前位置: 首页 > news >正文

CSS之重绘与回流

重绘(Repaint)

当页面中元素样式的改变并不影响它在文档流中的位置时(例如改变颜色、阴影等),浏览器会进行重绘,即重新绘制元素的外观。

回流(Reflow)

当元素的大小、位置、隐藏等改变时,浏览器需要重新计算元素的几何信息,并重新渲染页面,这个过程称为回流。会影响当前元素、祖先元素和后代元素。

性能影响

  • 回流比重绘的代价要高。回流的过程比重绘复杂,因为它涉及到更多的计算。
  • 回流必将引发重绘,而重绘不一定会引发回流。

触发条件

  • 添加或删除可见的DOM元素
  • 元素尺寸改变
  • 内容变化,例如用户在input框中输入文字
  • 页面渲染初始化
  • 浏览器窗口尺寸改变 —— 触发重排(回流)。

如何减少重绘和回流

  • 使用transform替代top。
  • 使用visibility替换display: none —— 因为前者只会触发重绘,后者会触发回流(重排)。
  • 不要使用table布局,因为可能很小的一个小改动会导致整个table的重新布局。
  • 避免在循环中对DOM进行频繁操作,可以使用documentFragment进行批量操作。
  • 避免频繁地读取会引发回流/重绘的属性,如果需要多次使用,可以用变量缓存起来。

代码示例

回流

HTML:

<div id="container"><p>Some text here...</p>
</div>

JavaScript:

let container = document.getElementById('container');// 这里会触发回流,因为改变了元素的几何属性
container.style.padding = '20px';// 这又触发了一次回流
container.style.borderWidth = '5px';

为了减少回流,可以合并多次改变样式的操作,使用cssText合并成一次操作:

container.style.cssText = 'padding: 20px; border-width: 5px;';

或者使用CSS类:

.custom-style {padding: 20px;border-width: 5px;
}
container.classList.add('custom-style');

重绘

CSS:

<head><style>.box {width: 100px;height: 100px;background-color: blue;}</style>
</head>
<body><div class="box"></div>
</body>

JavaScript:

document.querySelector('.box').style.backgroundColor = 'red';

这段代码改变了盒子的外观而没有改变它的布局,因此仅仅会导致重绘。

减少重绘和回流

1.使用cssText或者CSS类代替多次DOM操作

2. 使用fragment或clone

当需要对DOM进行大量修改时,最好的做法是使用DocumentFragment或者是clone一个元素,在副本上进行所有操作,然后再把它放回文档中。

let list = document.getElementById('list'),frag = document.createDocumentFragment(),items = ['Item 1', 'Item 2', 'Item 3'];// 使用DocumentFragment作操作
items.forEach(item => {let li = document.createElement('li');li.textContent = item;frag.appendChild(li);
});// 把DocumentFragment一次性添加到DOM中,减少页面回流
list.appendChild(frag);

这样做的好处在于减少了页面的回流次数:不是每添加一个列表项就回流一次,而是所有项都准备好之后才触发一次回流。

相关文章:

  • StringJoiner
  • GEE:关于在GEE平台上进行回归计算的若干问题
  • 3秒实现无痛基于Stable Diffusion WebUI安装ComfyUI!无需重复安装环境!无需重复下载模型!安装教程
  • 通过 Prometheus 编写 TiDB 巡检脚本(脚本已开源,内附链接)
  • 【Unity】【VR开发】针对VR项目的优化版Unity Build Settings
  • 人工智能学习与实训笔记(四):神经网络之NLP基础—词向量
  • [力扣 Hot100]Day28 两数相加
  • 使用 C++23 从零实现 RISC-V 模拟器(1):最简CPU
  • Java学习第十六节之类与对象的创建和构造器详解
  • 1.初识Tauri
  • ES实战-聚集
  • Rust基础拾遗--辅助功能
  • 惠普打印机驱动安装
  • 项目第一次git commit后如何撤销
  • JS进阶——垃圾回收机制以及算法
  • hexo+github搭建个人博客
  • $translatePartialLoader加载失败及解决方式
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 5、React组件事件详解
  • Asm.js的简单介绍
  • FineReport中如何实现自动滚屏效果
  • HTML-表单
  • iOS 颜色设置看我就够了
  • rabbitmq延迟消息示例
  • scrapy学习之路4(itemloder的使用)
  • 反思总结然后整装待发
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 线性表及其算法(java实现)
  • 小李飞刀:SQL题目刷起来!
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​学习一下,什么是预包装食品?​
  • #Spring-boot高级
  • #前后端分离# 头条发布系统
  • #微信小程序(布局、渲染层基础知识)
  • (1)SpringCloud 整合Python
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (12)目标检测_SSD基于pytorch搭建代码
  • (13)Hive调优——动态分区导致的小文件问题
  • (C语言)字符分类函数
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (五)网络优化与超参数选择--九五小庞
  • .NET CF命令行调试器MDbg入门(一)
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .net反混淆脱壳工具de4dot的使用
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • :如何用SQL脚本保存存储过程返回的结果集
  • @property python知乎_Python3基础之:property
  • @取消转义
  • [ 数据结构 - C++]红黑树RBTree
  • [AutoSar]工程中的cpuload陷阱(三)测试
  • [bzoj 3124][sdoi 2013 省选] 直径
  • [BZOJ] 3262: 陌上花开