资讯专栏INFORMATION COLUMN

浏览器的回流和重绘及其优化方式

hearaway / 555人阅读

摘要:何时发生有大量的用户行为以及潜在的改变会触发回流。这样就会让多次的回流重绘变成一次回流重绘。因为上的操作不会引发回流和重绘。参考文章回流与重绘性能让变慢参考文章浏览器的重绘与重排

推荐了解的知识:基本的HTML,基本的JavaScript,以及一些css工作原理方面的知识

浏览器的渲染原理

css的加载和解析不会阻塞html文档的解析

css的解析会阻塞js的执行,必须等到CSSOM生成后才能执行js

js的执行会阻塞html文档的解析

html一边解析一边显示

css必须完全解析完毕才能进入生成渲染树环节
       浏览器向服务器请求到了HTML文档后便开始解析,产物是DOM Tree(文档对象模型),如果有css,会根据css生成CSSOM(CSS对象模型),然后再由DOM和CSSOM合并产生Render Tree渲染树,有了渲染树,知道了所有节点的样式,便根据这些节点以及样式计算它们在浏览器中确切的大小和位置,这就是布局。最后把节点绘制到浏览器上。

创建DOM树—创建CSSOM树—执行脚本—生成渲染树—生成布局—绘制

回流

       回流(reflow)当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变时,网络浏览器重新渲染部分或全部文档的过程。

重绘

       当页面元素样式改变不影响元素在文档流中的位置时(如background-color,border-color,visibility),浏览器只会将新样式赋予元素并进行重新绘制操作。

       因为回流(reflow)在浏览器中属于一种用户主导的模块化操作,所以知道如何去改进回流(reflow)时间以及知道各种文档属性(DOM节点深度,css的渲染效率,各种各样的样式改变)对回流(reflow)时间的影响对于开发人员讲是很有帮助的。有时候,即使仅仅回流一个单一的元素,也可能要求它的父元素以及任何跟随它的元素也产生回流。

何时发生

       有大量的用户行为以及潜在的DHTML改变会触发回流(reflow)。例如,改变浏览器窗口的大小,使用一些JavaScript方法,包括计算样式,对DOM进行元素的添加或删除,或是改变元素的class等。

添加或者删除可见的DOM元素;

元素位置改变;

元素尺寸改变——边距、填充、边框、宽度和高度

内容变化,比如用户在input框中输入文字,文本或者图片大小改变而引起的计算值宽度和高度改变

页面渲染初始化

浏览器窗口尺寸改变——resize事件发生时

计算 offsetWidth 和 offsetHeight 属性

设置 style 属性的值

       回流必将引起重绘,而重绘不一定会引起回流。

性能优化

       回流比重绘的代价要更高,回流的花销跟render tree有多少节点需要重新构建有关系;浏览器本身能够进行优化,尽可能减少重绘和回流。
       如果每行JS代码操作DOM都需要回流重绘的话,浏览器可能就会受不了。所以很多浏览器都会优化这些操作,浏览器会维护1个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会flush队列,进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。
       当你请求向浏览器请求一些 style信息的时候,就会让浏览器flush队列,比如:

offsetTop, offsetLeft, offsetWidth, offsetHeight

scrollTop/Left/Width/Height

clientTop/Left/Width/Height

width,height

请求了getComputedStyle(), 或者 IE的 currentStyle

       当你请求上面的一些属性的时候,浏览器为了给你最精确的值,需要flush队列,因为队列中可能会有影响到这些值的操作。即使你获取元素的布局和样式信息跟最近发生或改变的布局信息无关,浏览器都会强行刷新渲染队列。

如何减少回流、重绘
var s = document.body.style; 

s.padding = "2px"; // 回流+重绘

s.border = "1px solid red"; // 再一次 回流+重绘

s.color = "blue"; // 再一次重绘

s.backgroundColor = "#ccc"; // 再一次 重绘

s.fontSize = "14px"; // 再一次 回流+重绘

// 添加node,再一次 回流+重绘
document.body.appendChild(document.createTextNode("abc!"));

///可以看到每次DOM元素的样式操作都会引发重绘,如果涉及布局还会引发回流。

一. CSS中避免回流

尽可能在DOM树的最末端改变class

避免设置多层内联样式

动画效果应用到position属性为absolute或fixed的元素上

牺牲平滑度换取速度

避免使用table布局

避免使用CSS的JavaScript表达式

二. JS操作避免回流

避免逐项更改样式。最好一次性更改style属性,或者将样式列表定义为class并一次性更改class属性。

避免循环操作DOM。创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。

也可以在一个display:none的元素上进行操作,最终把它显示出来。因为display:none上的DOM操作不会引发回流和重绘。

避免循环读取offsetLeft等属性。在循环之前把它们存起来。

绝对定位具有复杂动画的元素。绝对定位使它脱离文档刘,否则会引起父元素及后续元素大量的回流。

参考文章:回流与重绘:CSS性能让JavaScript变慢?
参考文章:浏览器的重绘(repaints)与重排(reflows)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/51284.html

相关文章

  • 回流重绘及其优化

    摘要:回流重绘及其优化渲染过程渲染引擎通过通过网络请求接收渲染内容解析抽象抽象出布局绘画抽象渲染引擎的第一步是解析文档并将解析的元素转换为树中的实际节点。 回流、重绘及其优化 渲染过程 渲染引擎通过通过网络请求接收渲染内容 解析HTML抽象DOM tree 抽象出Render tree 布局(layout)render tree 绘画render tree 抽象DOM tree 渲染引擎...

    Clect 评论0 收藏0
  • 回流重绘及其优化

    摘要:回流重绘及其优化渲染过程渲染引擎通过通过网络请求接收渲染内容解析抽象抽象出布局绘画抽象渲染引擎的第一步是解析文档并将解析的元素转换为树中的实际节点。 回流、重绘及其优化 渲染过程 渲染引擎通过通过网络请求接收渲染内容 解析HTML抽象DOM tree 抽象出Render tree 布局(layout)render tree 绘画render tree 抽象DOM tree 渲染引擎...

    Sike 评论0 收藏0
  • 回流重绘及其优化

    摘要:回流重绘及其优化渲染过程渲染引擎通过通过网络请求接收渲染内容解析抽象抽象出布局绘画抽象渲染引擎的第一步是解析文档并将解析的元素转换为树中的实际节点。 回流、重绘及其优化 渲染过程 渲染引擎通过通过网络请求接收渲染内容 解析HTML抽象DOM tree 抽象出Render tree 布局(layout)render tree 绘画render tree 抽象DOM tree 渲染引擎...

    alaege 评论0 收藏0
  • 览器回流重绘

    摘要:例如对于复杂动画效果,由于会经常的引起回流重绘,因此,我们可以使用绝对定位,让它脱离文档流,成为一个单独的图层。 浏览器的渲染过程 showImg(https://segmentfault.com/img/bVblB7y?w=624&h=289); 从上面这个图上,我们可以看到,浏览器渲染过程如下 解析HTML生成DOM树,解析CSS生成CSSOM树 将DOM树和CSSOM树结合生成...

    renweihub 评论0 收藏0
  • 览器回流重绘

    摘要:例如对于复杂动画效果,由于会经常的引起回流重绘,因此,我们可以使用绝对定位,让它脱离文档流,成为一个单独的图层。 浏览器的渲染过程 showImg(https://segmentfault.com/img/bVblB7y?w=624&h=289); 从上面这个图上,我们可以看到,浏览器渲染过程如下 解析HTML生成DOM树,解析CSS生成CSSOM树 将DOM树和CSSOM树结合生成...

    zhoutk 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<