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

重排和重绘

一、重绘(Repaint)

(一)定义

重绘是指当页面中某个元素的外观发生变化(但不改变其几何属性,如位置、尺寸等)时,浏览器重新绘制该元素的过程。

(二)触发条件
  1. 元素的背景色、颜色、字体等样式属性发生变化,例如将文字颜色从黑色改为红色。
  2. 元素的可见性(visibility)改变,例如从可见变为隐藏,或者相反。不过需要注意的是,visibility:hidden虽然会使元素不可见,但仍会为其保留空间,不影响页面布局;而display:none则是将元素完全从页面布局中移除。
  3. 元素的阴影(box-shadow、text-shadow等)发生变化,这会改变元素的视觉效果,但不改变其在页面布局中的位置和大小。
  4. 元素的透明度(opacity)改变,例如从完全不透明变为半透明状态。
(三)性能影响
  • 重绘主要涉及元素外观的重新绘制,不涉及布局计算,相对重排来说性能开销较小。
  • 但若大量元素频繁重绘,如动画效果中的每一帧都对多个元素进行外观修改,累积起来也会对性能产生较大影响,导致页面卡顿。

二、重排(Reflow)

(一)定义

重排也被称为回流,是当页面的布局发生变化(如元素的位置、尺寸或隐藏/显示状态改变等)时,浏览器重新计算页面的布局,并且通常会伴随着重绘的过程。

(二)触发条件
  1. DOM操作
    • 添加、删除或修改可见的DOM元素。例如在页面中动态添加一个div元素,或者删除一个按钮元素,都会导致浏览器重新计算页面布局,因为这些操作改变了页面的结构。
    • 改变元素的显示/隐藏状态,如通过display属性来控制元素的显示与隐藏。当display属性从none变为block,或者相反时,浏览器需要重新确定该元素在页面中的位置和大小。
  2. 几何属性改变
    • 修改元素的位置(如left、top、right、bottom、margin、padding等属性变化)、尺寸(如width、height等属性变化)、边距、内边距、边框等几何属性。例如,将一个div元素的宽度从100px增加到200px,这不仅改变了该元素的大小,还可能影响其周围元素的布局。
  3. 内容变化
    • 元素的内容发生变化,例如文本数量增多或减少、图片大小改变等。以文本内容为例,如果一段文字的长度变长,可能会导致包含该文字的元素宽度增加,进而影响父元素和其他兄弟元素的布局。
  4. 浏览器窗口大小变化
    • 当用户调整浏览器窗口大小时,页面的布局需要重新适应新的窗口尺寸,从而触发重排。
  5. 其他情况
    • 激活CSS伪类,如当鼠标悬停在元素上触发:hover伪类时,若伪类中定义了改变布局的样式(如改变元素的宽度),就会引起重排。
    • 调用某些方法或查询某些属性,如offsetWidth、offsetHeight、getComputedStyle()等。这些操作会强制浏览器进行同步操作,导致重排。
(三)性能影响
  • 重排的性能开销较大,因为需要重新计算页面布局,这涉及多个元素甚至整个页面的重新布局。
  • 重排会触发重绘,而且一次重排可能会引发多次重绘。例如,当一个元素的大小改变时,它可能会影响其父元素和其他兄弟元素的布局,这些元素都需要重新计算位置和尺寸,然后重新绘制。
(四)重排示例

假设有一个简单的HTML页面布局如下:

<div class="container"><div class="box" id="box1"></div><div class="box" id="box2"></div>
</div>

CSS样式为:

.container {display: flex;height: 100px;
}.box {width: 100px;height: 100px;background-color: red;margin: 10px;
}

如果通过JavaScript改变第一个盒子元素(box1)的宽度:

document.getElementById('box1').style.width = '200px';

这时浏览器会进行重排:

  1. 首先,浏览器发现box1的宽度发生了变化。
  2. 由于box1和box2在同一个flex容器中,box1的宽度增加会影响它们在容器中的布局。
  3. 浏览器需要重新计算box1和box2的位置和尺寸,以及它们之间的间距(margin)等布局信息。
  4. 同时,容器元素(container)的布局也可能受到影响,需要重新确定其内部空间的分配。
  5. 最后,浏览器根据新的布局信息重新绘制这些元素。

三、重绘和重排的区别与联系

(一)区别
  • 触发条件不同:重绘是由于元素外观改变(如颜色、阴影等)而触发;重排是由于元素布局改变(如大小、位置等)而触发。
  • 性能开销不同:重排通常比重绘性能开销大,因为它涉及布局计算,并且可能引发重绘。
(二)联系
  • 重排几乎总是会引发重绘,因为布局变化后,元素的外观呈现往往也需要更新。
  • 重绘不一定会引起重排,但如果重绘的元素在布局上发生变化(例如通过改变font-size间接影响元素宽度),也可能导致重排。

四、优化重绘和重排的建议

(一)针对重绘的优化
  1. 减少不必要的样式变化:尽量避免频繁地修改元素的外观样式,特别是对于大量元素的动画效果,可以考虑使用CSS动画和过渡,它们通常比JavaScript操作样式更高效。
  2. 使用CSS类来修改样式:通过添加或移除CSS类来改变元素样式,而不是直接操作元素的style属性。这样可以更好地控制样式变化,并且有利于批量操作和样式管理。
  3. 延迟非关键的重绘操作:对于一些对用户体验影响不大的重绘操作,可以考虑延迟执行,例如在页面加载完成后或用户交互的空闲时间再进行。
(二)针对重排的优化
  1. 减少DOM操作:尽量减少对DOM元素的增删改操作,特别是批量操作时,可以先将元素从DOM中移除,进行修改后再重新插入。
  2. 使用文档片段(DocumentFragment):当需要向页面中添加大量DOM节点时,可以先将它们添加到文档片段中,最后再将文档片段统一插入文档中。这样可以减少重排次数,因为文档片段在内存中操作,不会立即触发重排。
  3. 避免频繁查询布局信息:避免在循环中频繁查询如offsetWidth、offsetHeight等布局信息,因为这会强制浏览器进行重排。可以将这些信息先存储起来,再进行后续操作。
  4. 使用CSS的will-change属性:可以提前告知浏览器哪些元素的属性将会发生变化,例如:
    .element {will-change: transform;
    }
    
    浏览器会根据这个提示进行一些性能优化,如提前分配资源等。
  5. 避免使用table布局:table布局在重排时性能较差,因为表格的大小和单元格的大小相互依赖,修改一个单元格的大小可能会导致整个表格重新布局。尽量使用CSS Grid和Flex布局,它们提供了更灵活、高效的布局方式。

五、引起重排和重绘的属性

(一)引起重排的属性

引起重排的属性主要是与页面布局相关的属性,包括:

  • 盒模型

    • display: 改变元素的显示类型(如blockinlineflex等)会影响元素的布局。
    • padding, margin, width, height: 直接影响元素的尺寸和周围的空间。
    • min-height, max-height, border, border-width: 改变这些属性会影响元素的尺寸和边框。
  • 定位和浮动

    • position: 改变元素的定位方式(如relativeabsolutefixed等)会影响其在页面中的位置。
    • top, bottom, left, right: 定位属性的改变会影响绝对或相对定位元素的位置。
    • float, clear: 浮动属性的改变会影响元素的布局和周围元素的排列。
  • 文字及溢出

    • font-family, font-size, font-weight: 文本字体和大小的变化可能影响元素的宽度和高度。
    • line-height, text-align, vertical-align, white-space: 这些属性的变化会影响文本在元素中的排列和元素的高度。
    • overflow, overflow-y: 溢出属性的改变会影响元素的内容显示和滚动条的出现。
(二)引起重绘的属性

引起重绘的属性主要是与元素外观相关的属性,包括:

  • 颜色

    • color: 改变文本颜色。
  • 边框

    • border-color, border-style, border-radius: 改变边框的颜色、样式和圆角。
  • 背景

    • background, background-image, background-position, background-repeat, background-size: 改变背景的显示方式和位置。
  • 轮廓

    • outline, outline-color, outline-style, outline-width: 改变轮廓的显示方式。
  • 可见性

    • visibility: 改变元素的可见性(如visiblehidden)。
  • 文字方向

    • text-decoration: 改变文本的装饰(如下划线、删除线)。
  • 发光

    • box-shadow: 改变元素的阴影效果。

六、避免重排和重绘的优化建议

(一)尽量使用仅引起合成的属性
  • 使用transformopacity等属性进行动画,因为它们不会引起重排或重绘,而是通过合成来实现。
(二)限制重新渲染区域
  • 使用position: absoluteposition: fixed等方法创建层叠上下文,减少重排的范围。
  • 使用contain: layoutcontain: paint等属性值,使当前元素和内容独立于DOM树,减少重排的影响。
(三)减少使用display: table<table>表格布局
  • 表格布局在重排时性能较差,尽量使用CSS Grid和Flex布局。
(四)其他优化建议
  • 减少DOM操作:尽量合并多次DOM操作,减少重排的次数。
  • 使用文档片段(DocumentFragment):批量添加元素时,先将元素添加到文档片段中,再统一插入文档。
  • 避免频繁查询布局信息:避免在循环中频繁查询offsetWidthoffsetHeight等布局信息,可以将这些信息提前存储起来。
http://www.xdnf.cn/news/3830.html

相关文章:

  • 广东省考备考(第一天5.4)—判断(对称)
  • 组合模式深度解析:构建灵活树形结构的终极指南
  • Spring AI 实战:第四章、Spring AI多模态之看图说话
  • 四、shell脚本--流程控制语句:指挥脚本“走哪条路”
  • C++ 建造者模式详解
  • 第13章:陈默再访海奥华
  • QT下根据深度信息计算物体尺寸并UI显示的简单方案
  • 【翻译、转载】MCP 核心架构
  • Docker 容器化部署
  • 信息系统监理师第二版教材模拟题第三组(含解析)
  • CSS定位详解
  • 【Linux系统】条件变量
  • Cona编译问题
  • Web网页布局
  • 赋予网页健壮的灵魂 —— TypeScript(下)
  • Circular Plot系列(五): circle plot展示单细胞互作
  • 电动调节V型球阀的作用:专为颗粒状含碱浆液介质打造的高效解决方案-耀圣
  • 第 14 届蓝桥杯 C++ 青少组省赛中 / 高级组真题解析
  • 开源项目:optimum-quanto库介绍
  • 全面掌握 Jetpack Compose 的 State 体系:核心用法与最佳实践
  • 动态规划(5)路径问题--剑指offer -珠宝的最大值
  • 7 微调 黑盒蒸馏 突破伦理限制
  • STM32外设-GPIO输入(仅数字)
  • [GESP202503 四级] 二阶矩阵c++
  • Spring AI 实战:第八章、Spring AI Tool Calling之与时俱进
  • Android Framework学习三:zygote剖析
  • 轻量化定时工具!Pt 极简界面 :定时备份 + 循环灵活关机
  • 基于springboot3+mybatis整合,使用mybatisPlus插件自动完成简单的 增删改查操作
  • LeetCode 热题 100 189. 轮转数组
  • 多语言笔记系列:Polyglot Notebooks 混合使用多语言并共享变量