浏览器重绘(repaint)和回流(reflow)的那点事
第一次听到重绘和回流是在鹅厂实习面试,那个时候对浏览器没有任何的概念,所以面试官说到这个问题的时候整个人都蒙圈了。下面是近期学习总结:
重绘(repaint)和回流(reflow)
文档初次加载时,HTML解析器会解析元素构建DOM树,CSS解析器将样式解析为样式结构体,之后通过DOM树和样式结构体构建渲染树,渲染树具有样式属性。然后遍历渲染树的每个渲染器将器布局到页面,最后浏览器将器绘制到页面。
重绘:当元素的外观或外观可见性(visibility)发生变化时会触发重绘
回流:render树中的部分或全部因为元素的规模尺寸、布局、隐藏等改变,需要重新计算render树。
回流时,浏览器会使渲染树中受影响的部分失效,然后重新构造这部分的render树。完成回流之后浏览器会重新布局、绘制受影响的部分到屏幕中,该过程就是重绘。所以回流必定会引起重绘,但重绘不一定引起回流。
每个页面至少需要一次回流,就是页面第一次加载时。回流变化涉及到部分页面(或整个页面)的布局。一个元素的回流导致其所有子元素以及DOM中紧随其后的祖先元素和其子元素都发生回流。
是什么导致回流呢?
(1) 调整窗口大小----发生resize事件时
(2) 元素位置改变
(3) 元素尺寸改变——边距、填充、边框、高度和宽度
(4) 内容改变——比如文本字体或图片大小改变而引起的宽度和高度改变
(5) 页面渲染初始化
(6) 添加或删除可见的DOM元素
聪明的浏览器
很多浏览器都会优化repaint和reflow操作,浏览器会维护1个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会把flush队列,进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。 虽然有了浏览器的优化,但有时候我们写的一些代码可能会强制浏览器提前flush队列,比如设置width,offsetTop,scrollTop,clientTop精确值时,这样浏览器的优化可能就起不到作用了。
避免回流和重绘方法
减少回流、重绘其实就是需要减少对render tree的操作,并减少对一些style信息的请求,尽量利用好浏览器的优化策略
(1) 避免操作DOM,创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。也可以在一个display:none的元素上进行操作,最终把它显示出来。因为display:none上的DOM操作不会引发回流和重绘。
(2) 让要操作的元素进行"离线处理",处理完后一起更新,这里所谓的"离线处理"即让元素不存在于render tree中。如读取offsetLeft等属性。
(3) 尽可能在DOM树的末端改变class ,尽可能在DOM树的里面改变class,可以限制回流的范围,使其影响尽可能少的节点。
(4) 避免设置多层内联样式,因为每一个都会造成回流,样式合并在一个外部类,这样当该元素的class属性被操作时,只会产生一个reflow。
(5) 将需要多次回流的元素position属性设为absolute或fixed,这样该元素就会脱离文档流,它的变化不会影响其他元素变化。比如动画效果应用到position属性为absolute或fixed的元素上。
(6) 牺牲平滑度换取速度,动画元素每次移动3像素可能在非常快的机器上看起来平滑度低了,但它不会导致CPU在较慢的机器和移动设备中抖动
(7) 避免使用table布局,在布局完全建立之前,table需要很多关口,table是可以影响之前已经进入的DOM元素的显示的元素。即使一些小的变化和会导致table中所有其他节点回流。
(8) 避免使用css的JavaScript表达式,该规则较过时,但是个好主意。因为每次都需要重新计算文档,或部分文档、回流。
浏览器重绘(repaint)和回流(reflow)的那点事的更多相关文章
- 页面重绘(repaint)和回流(reflow)
前言 页面显示到浏览器上的过程: 1.1.生成一个DOM树. 浏览器将获取到的HTML代码解析成1个DOM树,包含了所有标签,包括display:none和动态添加的节点. 1.2.生成样式结构体. ...
- 页面优化,谈谈重绘(repaint)和回流(reflow)
一.前言 偶尔在面试过程中遇到过重汇与回流reflow的问题,毕竟页面优化也是考核一个开发者能力的关键之一,上篇文章聊了下documentfragment也是为了减轻回流问题,那么本篇文章好好介绍下重 ...
- 回流(reflow)与重绘(repaint)
回流(reflow)与重绘(repaint) 很早之前就听说过回流与重绘这两个名词,但是并不理解它们的含义,也没有深究过,今天看了一套网易的题目,涉及到了这两个概念,于是想要把它们俩弄清楚... 一. ...
- 什么是回流(重排 reflow)?什么是重绘(repaint)?如何减少回流、重绘?
什么是回流(重排 reflow)? 回流(重排 reflow):对DOM树进行渲染,只要修改DOM或修改元素的形状大小,就会触发reflow,reflow的时候,浏览器会使已渲染好受到影响的部分失效, ...
- 翻译:让网络更快一些——最小化浏览器中的回流(reflow)
关于reflowreflow(英音:[ri:’fləu] 美音:[ri’flo])在词典中的解释是回流,逆流.而在web应用中,翻译为回流有些牵强.我个人觉得,理解为回炉(重新塑形),似乎更加形象一点 ...
- 前端性能优化--回流(reflow)和重绘(repaint)
HTML加载时发生了什么 在页面加载时,浏览器把获取到的HTML代码解析成1个DOM树,DOM树里包含了所有HTML标签,包括display:none隐藏,还有用JS动态添加的元素等. 浏览器把所有样 ...
- 浏览器的重绘与回流(Reflow & Repaint)介绍
重绘 当页面元素样式改变不影响元素在文档流中的位置时(如background-color,border-color,visibility),浏览器只会将新样式赋予元素并进行重新绘制操作. 回流 当改变 ...
- CSS 回流(reflow)
摘录: 1. 回流 回流是指浏览器为了重新渲染部分或者全部的文档而重新计算文档中元素的位置和几何构造的过程. 因为回流可能导致整个dom树的重新构造,所以会影响性能. 2. display:no ...
- 【翻译】浏览器渲染Rendering那些事:repaint、reflow/relayout、restyle
原文链接:http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/ 有没有被标题中的5个“R”吓到?今天,我们来讨论一下浏览器的渲 ...
随机推荐
- (转)jquery $.proxy的使用
在某些情况下,我们调用Javascript函数时候,this指针并不一定是我们所期望的那个.例如: 1 //正常的this使用 2 $('#myElement').click(function() { ...
- Javaweb基础--->Servlet(转载)
今天看到这篇博客,感觉还不错,拿来借鉴学习一下. 一.Servlet 是什么? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客 ...
- virt-v2v 使用指南
virt-v2v 使用指南 1.定义. virt-v2v将外部的虚拟化平台上的虚拟机转化到可以运行的KVM平台上.它可以读取在VMware.Xen运行Hyper-V和其他虚拟机管理程序上的Window ...
- Floyd 学习笔记
#include <cstdio> #include <cstring> #include <ctype.h> #include <cstdlib> # ...
- 培训笔记——Linux基本命令
在介绍命令之前,更重要的要先介绍一下快速输入命令的方法. 如果你能记住一些常用命令,毫无疑问,通过命令的操作方式比通过鼠标的操作方式要快. 但是有一些命令或是命令用到的参数如文件名特别复杂特别长,这时 ...
- Data Structure Array: Given an array of of size n and a number k, find all elements that appear more than n/k times
http://www.geeksforgeeks.org/given-an-array-of-of-size-n-finds-all-the-elements-that-appear-more-tha ...
- 剑指offer——扑克牌的顺子
思想: 1.先将输入的几个数进行排序,sort函数是#include<algorithm>下的. 2.统计0的个数,以及相邻数的差值,比较0的个数及差值的和.看是否可以用大王填充中间的差值 ...
- matlab之fliplr()函数
fliplr 左右翻转矩阵 语法: B = fliplr(A) 将矩阵A的列绕垂直轴进行左右翻转 matabc 如果A是一个行向量,fliplr(A)将A中元素的顺序进行翻转. 如果A是一个列向量, ...
- JavaScript中call、apply个人理解
JavaScript中call.apply个人理解 一句话即通俗的说:call.apply 是为了改变this的状态而存在的 }; } function personInfo(name,age){ t ...
- mvc购物车项目(2)
为了避免数据冗余,我们可以把共同的信息,抽出建立一个单独的表,把不是共有的信息,建立一张单独表. 订单表分为两个表 create table orders( id number primary key ...