浏览器重绘(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”吓到?今天,我们来讨论一下浏览器的渲 ...
随机推荐
- CentOS iSCSI服务器搭建------Target篇
先上服务器信息(当然是我YY的服务器.哈哈) [root@node ~]# cat /etc/redhat-release CentOS release 6.6 (Final) [root@node ...
- Linux vim 中文显示乱码解决方法
因为在windows下默认是gb编码,而我的vim默认是utf-8(gedit默认也是utf-8),所以打开会成乱码.改动了一下配置文件,使vi支持gb编码就好了.$vi ~/.vimrclet &a ...
- linux清空屏幕
linux清空屏幕 clear ctrl+L reset也是真正的清空终端屏幕,这个命令执行起来有点慢,但它的兼容性显然比之前的那个好,在终端控制错乱时非常有用
- [算法]打印N个数组的整体最大Top K
题目: 有N个长度不一的数组,所有的数组都是有序的,请从大到小打印这N个数组整体最大的前K个数. 例如: 输入含有N行元素的二维数组代表N个一维数组. 219,405,538,845,971 148, ...
- 012_流式计算系统(Mahout协同过滤)
课程介绍 课程内容 1.Mahout是什么 l Mahout是一个算法库,集成了很多算法. l Apache Mahout 是 Apache Software Foundation(ASF)旗下的 ...
- Git_学习_01_ 常用 Git 命令清单
我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下 ...
- Java基础 之 System.getProperty()方法
Java基础 之 System.getProperty()方法大全 public static void main(String[] args) { System.out.println(" ...
- c#迭代遍历带数组的json格式数据
[1]首先我们先创建一个带数组形式的json格式的数组 1)我们按照结构定义一个类,如下: using System;using System.Collections.Generic;using Sy ...
- 通过Jquery异步获取股票实时数据
最近朋友让我帮他做个异步获取数据的程序,暂时服务器什么都没有,所以我就想先拿股票数据打个框架,方便后续开发和移植等事情 代码如下: <!-- 说明:股票看盘 作者:黑桃A 时间:2014-04- ...
- Linux下eclipse及mysql安装,c++访问mysql数据库
这两天在学习linux下用c++访问mysql,碰到一堆问题,记录一下. 1.mysql安装: 公司的电脑是64位的,安装的是64为的RHEL4,安装如下三个包: MySQL-client-5.1.4 ...