介绍下重绘和回流(Repaint & Reflow),以及如何进行优化
1. 浏览器渲染机制
- 浏览器采用流式布局模型(
Flow Based Layout) - 浏览器会把
HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了渲染树(Render Tree)。 - 有了
RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上。 - 由于浏览器使用流式布局,对
Render Tree的计算通常只需要遍历一次就可以完成,但table及其内部元素除外,他们可能需要多次计算,通常要花3倍于同等元素的时间,这也是为什么要避免使用table布局的原因之一。
2. 重绘
由于节点的几何属性发生改变或者由于样式发生改变而不会影响布局的,称为重绘,例如outline, visibility, color、background-color等,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。
3. 回流
回流是布局或者几何属性需要改变就称为回流。回流是影响浏览器性能的关键因素,因为其变化涉及到部分页面(或是整个页面)的布局更新。一个元素的回流可能会导致了其所有子元素以及DOM中紧随其后的节点、祖先节点元素的随后的回流。
<body>
<div class="error">
<h4>我的组件</h4>
<p><strong>错误:</strong>错误的描述…</p>
<h5>错误纠正</h5>
<ol>
<li>第一步</li>
<li>第二步</li>
</ol>
</div>
</body>
在上面的HTML片段中,对该段落(<p>标签)回流将会引发强烈的回流,因为它是一个子节点。这也导致了祖先的回流(div.error和body – 视浏览器而定)。此外,<h5>和<ol>也会有简单的回流,因为其在DOM中在回流元素之后。大部分的回流将导致页面的重新渲染。
回流必定会发生重绘,重绘不一定会引发回流。
4. 浏览器优化
现代浏览器大多都是通过队列机制来批量更新布局,浏览器会把修改操作放在队列中,至少一个浏览器刷新(即16.6ms)才会清空队列,但当你获取布局信息的时候,队列中可能有会影响这些属性或方法返回值的操作,即使没有,浏览器也会强制清空队列,触发回流与重绘来确保返回正确的值。
主要包括以下属性或方法:
offsetTop、offsetLeft、offsetWidth、offsetHeightscrollTop、scrollLeft、scrollWidth、scrollHeightclientTop、clientLeft、clientWidth、clientHeightwidth、heightgetComputedStyle()getBoundingClientRect()
所以,我们应该避免频繁的使用上述的属性,他们都会强制渲染刷新队列。
5. 减少重绘与回流
CSS
使用
transform替代top使用
visibility替换display: none,因为前者只会引起重绘,后者会引发回流(改变了布局避免使用
table布局,可能很小的一个小改动会造成整个table的重新布局。尽可能在
DOM树的最末端改变class,回流是不可避免的,但可以减少其影响。尽可能在DOM树的最末端改变class,可以限制了回流的范围,使其影响尽可能少的节点。避免设置多层内联样式,CSS 选择符从右往左匹配查找,避免节点层级过多。
<div>
<a> <span></span> </a>
</div>
<style>
span {
color: red;
}
div > a > span {
color: red;
}
</style>对于第一种设置样式的方式来说,浏览器只需要找到页面中所有的
span标签然后设置颜色,但是对于第二种设置样式的方式来说,浏览器首先需要找到所有的span标签,然后找到span标签上的a标签,最后再去找到div标签,然后给符合这种条件的span标签设置颜色,这样的递归过程就很复杂。所以我们应该尽可能的避免写过于具体的 CSS 选择器,然后对于 HTML 来说也尽量少的添加无意义标签,保证层级扁平。将动画效果应用到
position属性为absolute或fixed的元素上,避免影响其他元素的布局,这样只是一个重绘,而不是回流,同时,控制动画速度可以选择requestAnimationFrame,详见探讨 requestAnimationFrame。避免使用
CSS表达式,可能会引发回流。将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点,例如
will-change、video、iframe等标签,浏览器会自动将该节点变为图层。CSS3 硬件加速(GPU加速),使用css3硬件加速,可以让
transform、opacity、filters这些动画不会引起回流重绘 。但是对于动画的其它属性,比如background-color这些,还是会引起回流重绘的,不过它还是可以提升这些动画的性能。
JavaScript
- 避免频繁操作样式,最好一次性重写
style属性,或者将样式列表定义为class并一次性更改class属性。 - 避免频繁操作
DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。 - 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
- 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
- 避免频繁操作样式,最好一次性重写
介绍下重绘和回流(Repaint & Reflow),以及如何进行优化的更多相关文章
- 重绘和回流(reflow和repaint)
由于DOM操作会导致浏览器的回流,回流需要花费大量的时间进行样式计算和节点重绘与渲染,所以应当尽量减少回流次数. 以下是几种常见的减少重绘和回流的方法: 一.不要一项一项的更改页面的样式,尽量一口气写 ...
- DOM的重绘和回流及代码性能优化
1.DOM的重绘和回流Repaint&Reflow 1.1重绘:元素样式的改变(但宽高.大小.位置等不变) 如outline.visibility.color.background-color ...
- 理解浏览器的重绘与回流(repaint&&reflow)
今天在做练习的时候,遇到了重绘与回流这个词,表示连个毛都没有听过.遂查之,首先将网上的(http://blog.sina.com.cn/s/blog_8dace7290102wezv.html)关于这 ...
- 重绘和回流(Repaint & Reflow)总结,以及如何进行优化
1. 浏览器渲染机制 浏览器采用流式布局模型(Flow Based Layout) 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了渲染树(Render Tre ...
- 浅谈JS重绘与回流
在说浏览器渲染页面之前,我们需要先了解两个点,一个叫 浏览器解析 URL,另一个就是本章节将涉及的 重绘与回流: 重绘(repaint):当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新, ...
- 【web性能】页面呈现、重绘、回流
在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...
- Qt重绘之update,repaint详解
Qt里面的重绘和Windows编程里面的重绘差不多.但是Qt的重绘更有特色,更加智能. 在讲之前,先说说paintEvent() paintEvent()是一个虚函数槽(slot),子类可以对父类的p ...
- 高性能WEB开发:深入理解页面呈现、重绘、回流
在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...
- Web前端性能优化-重绘与回流
1.什么是重绘与回流 Render tree 的重新构建就叫回流.当布局和几何属性改变时就需要回流,鼠标移动到图片 图片变大 也会触发回流.回流 能避免就避免 Render tree 改变外观.风格 ...
随机推荐
- sql server 取多条数据的最大值
实列: SELECT a.BillDate '[开票时间]', a.Hdbh '[运单号]', a.Status '运单状态', a.DisplayStatus '运单状态字', b.name '开票 ...
- mysql域名解析引起的远程访问过慢?
MYSQL远程连接速度慢的解决方法 PHP远程连接MYSQL速度慢,有时远程连接到MYSQL用时4-20秒不等,本地连接MYSQL正常,出现这种问题的主要原因是, 默认安装的MYSQL开启了DNS的反 ...
- Maven和Gradle如何添加依赖
仓库地址:https://mvnrepository.com
- mysql explain的type的
导语 很多情况下,有很多人用各种select语句查询到了他们想要的数据后,往往便以为工作圆满结束了.这些事情往往发生在一些学生亦或刚入职场但之前又没有很好数据库基础的小白身上,但所谓闻道有先后,只要我 ...
- Android学习笔记通过Toast显示消息提示框
显示消息提示框的步骤 这个很简单我就直接上代码了: Button show = (Button)findViewById(R.id.show); show.setOnClickListener(new ...
- cb44a_c++_STL_算法_删除_(2)remove_copy_remove_copy_if
cb44a_c++_STL_算法_删除_(2)remove_copy_remove_copy_if remove_copy()//在复制过程中删除一些数据remove_copy_if() 删除性算法: ...
- JVM之HotSpot虚拟机是如何发起内存回收的?
1.背景 在上一节中,我们掌握了垃圾收集的一些算法,也弄明白了分代回收的原理, 那么HotSpot虚拟机是如何发起内存回收的? 2.如何找到GC Roots根节点(枚举根节点) 从可达性分析中GC R ...
- Spring声明周期的学习心得
我们首先来看下面的一个案例: 这里是 HelloWorld.java 文件的内容: package com.yiibai; public class HelloWorld { private ...
- PHP输入流
PHP输入流php://input,对于这个的官方解释是: php://input可以读取没有处理过的POST数据.相较于$HTTP_RAW_POST_DATA而言,它给内存带来的压力较小,并且不需要 ...
- js语法基础入门(5.1)
5.流程控制 5.1.选择结构 程序流程图 图例: 椭圆: 开始/结束 矩形: 操作 菱形: 判断 连接线: 走向 可以根据程序流程图,理清楚程序执行的流程 5.2.1.if语句 //if语句语法结构 ...