面试的时候经常被问到,css重排(Reflow)和重绘(Repaint)。从字面意思也可以理解重排是重新排列,重绘是重新,绘制。
二、相关概念在了解Reflow和Repaint 之前我们需要了解以下几个概念。
2.1 Dom Tree在讲解dom tree 之前应该了解一下什么是dom?
DOM 全称是 Document Object Model,
译为文档对象模型。请注意里面的对象两字。
每个HTML标签都是一个对象,嵌套的标签是闭合的子标签。
DOM 由此可以将一段HTML 代码表示为标签的树型结构。只要内容在html中就会加入到dom tree 中,包括注释。
每一个树的节点都是一个对象
document
— DOM 的“入口点”。标签节点元素内的文本形成文本节点 标记为#text一个文本节点只包含一个字符串,没有节点,是树的叶子
a. 特殊字符(,
之前的空格和换行符均被忽略。)1.特殊字符↵ (js 中为\n)
2.空格␣注释节点类型(不会显示在dom中但是,js可以从dom中读取到)
示例:
DOCTYPE HTML>
<html>
<head>
<title>About elktitle>
head>
<body>
The truth about elk.
body>
html>
dom树结构
在了解了Dom Tree 之后,我们就可以进阶一步了解Render Tree。
dom节点:
可视化节点(div p 等这种结构性标签)非可视化节点(script meta 等在这种页面上显示不出来的节点)浏览器获取 HTML 文件,然后对文件进行解析,形成DOM Tree
与此同时,进行 CSS 解析,生成 Style Rules
接着将 DOM Tree 与 Style Rules 合成为 Render Tree
元素在页面中布局,然后绘制
render 树就是根据 可视化节点 和 css 样式表 结合诞生出来的树;
注意:PS: display: none 的元素会出现在 DOM树 中,但不会出现在 render 树中;
三、什么是Reflow?当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
引起回流的 *** 作
页面首次渲染浏览器窗口大小发生改变元素尺寸或位置发生改变元素内容变化(文字数量或图片大小等等)元素字体大小变化添加或者删除可见的DOM
元素激活CSS
伪类(例如::hover
)查询某些属性或调用某些方法
一些常用且会导致回流的属性和方法:
clientWidth
、clientHeight
、clientTop
、clientLeft
offsetWidth
、offsetHeight
、offsetTop
、offsetLeft
scrollWidth
、scrollHeight
、scrollTop
、scrollLeft
scrollIntoView()
、scrollIntoViewIfNeeded()
getComputedStyle()
getBoundingClientRect()
scrollTo()
四、什么是Repaint?
当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color
、background-color
、visibility
等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
当一个元素的外观发生改变的时候,但是并不改变布局,重新绘制元素的过程,叫做重绘。比如color
,background-color
,visibility
等相关元素背景,文字颜色,边框样式
在了解了回流和重绘的时候,我们可以得出。回流比重绘的代价要更高。
因为每次在回流 *** 作中,都需要生成一次Render Tree。
现代浏览器会对频繁的回流或重绘 *** 作进行优化:
浏览器会维护一个队列,把所有引起回流和重绘的 *** 作放入队列中,如果队列中的任务数量或者时间间隔达到一个阈值的,浏览器就会将队列清空,进行一次批处理,这样可以把多次回流和重绘变成一次。
六、如何针对回流和重绘进行优化 6.1 css 方面 避免使用table布局尽可能在dom树最末端改变class将动画效果应用到position属性为absolute或者fixed的元素上。(如果需要重排,尽量做局部重拍,不影响其他元素)避免使用css表达式 比如calc()有关第三点,其实就是分层,将全局重排变为局部重排,但是会有
6.2 js 方面 多个样式更改最好用一个calss去更改,避免重复 *** 作dom。可以将dom *** 作定义到一个变量中。最后添加到文本中可以对元素初始属性设置display: none , 对dom *** 作结束再让其显示出来。因为修改display:none ,不会引起dom的重排和重绘制 七、总结 7.1 浏览器渲染绘制可以将布局树中的元素分解为多个层。将内容提升到 GPU 上的层(而不是 CPU 上的主线程)可以提高绘制和重新绘制性能。有一些特定的属性和元素可以实例化一个层,包括
和
,任何 CSS 属性为
opacity
、3Dtransform
、will-change
的元素,还有一些其他元素。这些节点将与子节点一起绘制到它们自己的层上,除非子节点由于上述一个(或多个)原因需要自己的层。
分层确实可以提高性能,但是它以内存管理为代价,因此不应作为 web 性能优化策略的一部分过度使用。
浏览器获取 HTML 文件,然后对文件进行解析,形成 [[DOM Tree]]
与此同时,进行 CSS 解析,生成 Style Rules
接着将 DOM Tree 与 Style Rules 合成为 Render Tree
元素在页面中布局,然后绘制
render 树就是根据 可视化节点 和 css 样式表 结合诞生出来的树;
7.2 重排必定重绘,重绘不一定重排。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)