专栏首页前端杂谈性能优化之reflow和repaint

性能优化之reflow和repaint

本文主要介绍一下什么是reflow,repaint, 怎样避免它们造成的不良影响, 怎么通过工具查看分析它们.  

一.首先对浏览器渲染引擎下网页呈现过程简要说一下:

  1. 浏览器的渲染引擎开始解析html构建成DOM树,DOM树是以document对象为根节点,包含所有的html标签, 包括display: none隐藏的,也包括js动态添加的元素。
  2. 解析html的同时, 将css文件或者样式元素中的样式解析成CSS Rule Tree,解析时会去掉浏览器不能识别的样式。
  3. 根据DOM树和CSSOM来构造Rendering Trre。Rendering Trre和DOM Tree相比较,Rendering Trre中每个节点都包含样式信息,而且Render Tree不会包含隐藏的节点,只有影响到呈现的节点才会包含在Render Tree中(例如: display:none的节点,head节点不会包含在Render Tree中,visibility:hidden会被包含,因为它会影响layout)。
  4. 生成布局(layout),计算各节点元素在屏幕上所在位置和几何结构。
  5. 绘制(paint),将布局绘制到屏幕上。

以上5步中,主要耗时的是后2步,后两步合称为渲染(render)。

二: 什么是reflow 和 repaint:

  网页在生成的过程中,至少要渲染一次。之后在访问过程中,还会不断的进行渲染。重新渲染就行重新生成布局和绘制(也就是重复进行上面的第4,5步)重新生成布局的过程就是reflow(回流,重排),重新绘制就叫做reflow(重绘)。

三: 什么时候触发reflow和repaint

注: repaint不一定需要reflow,例如:改变某元素的颜色,只会触发repaint,不会触发reflow。但是reflow一定会导致repaint,因为布局改变了,就一定需要重新绘制。 Reflow 的成本比 Repaint 的成本高很多。DOM Tree里的每个节点都会有reflow方法,一个结点的reflow可能导致其子结点,甚至父点以及同级结点的 reflow。在PC端或许还没什么,但是在手机上,还是比较耗性能和耗电的。 以下情况会导致reflow:

  1. 增加货移除css样式
  2. 改变字体大小
  3. 改变窗口大小
  4. 操作class属性
  5. 激活css伪类
  6. 内容变化,如在input内输入文字
  7. js操作DOM
  8. 获取offsetTop, offsetLeft等layout属性
  9. 设置css属性等值

   ... ...

四.如何减小reflow的影响:

  1. 减少不必要的DOM层级.
  2. 避免使用table进行布局,因为可能很小的一个小改动会造成整个 table 的重新布局。
  3. 尽量通过position属性为absolute或fixed实现动画效果
  4. 不要一条一条地修改 DOM 的样式。而是预先定义好对应的 class,然后修改对应节点的 className
  5. 不要逐条操作DOM节点:    a> 使用 documentFragment 对象在内存里操作 DOM。  b> 先把 DOM 给 display:none (有一次 repaint),做完所有的修改后,再把他显示出来。  c> clone 一个 DOM 节点到内存里,做完所有的修改后,再交换一下。
  6. 请求如下值offsetTop, offsetLeft, offsetWidth, offsetHeight,scrollTop/Left/Width/Height,clientTop/Left/Width/Height,浏览器会发生reflow,建议将他们合并到一起操作,可以减少回流的次数。多次要用到值,可以先用变量缓存起来.

  ... ...

五.开发者工具查看

  Chrome浏览器开发者工具的Performance面板,可以查看页面回流和重绘所花费的时间.   打开f12下的开发者工具, 切换到Performance面板.如下图:

  点击开始录制按钮,会开始录制,这时在网页上进行一些操作, 然后点击停止按钮,如下:

  从图中可以判断出性能问题到底出现在哪个环节,是js的执行,还是渲染

  图中不同颜色代表不同的事件, 哪个色块越大, 说明耗时越长,问题越大.可以根据此去进行优化.

  • 黄色: javaScript执行时间
  • 紫色: 样式重新计算和布局, 即reflow时间
  • 绿色: repaint时间

如何对线上项目进行性能监控

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • cookie方法封装及cookie缺点分析

    用户1741436
  • 让你的JS代码更具可读性

    用户1741436
  • es6之块级作用域

    用户1741436
  • 使用 Python 假装黑客,批量破解朋友的网站密码

    今天看了一篇关于如何破解iphone手机密码的文章,瞬间觉得科学技术不是第一生产力,why?

    小小詹同学
  • 使用python假装装黑客,批量破解朋友的网站密码

    今天看了一篇关于如何破解iphone手机密码的文章,瞬间觉得科学技术不是第一生产力,why?

    Python进阶者
  • 使用Python假装装黑客,批量破解朋友的网站密码

    今天看了一篇关于如何破解iphone手机密码的文章,瞬间觉得科学技术不是第一生产力,why?

    叫我龙总
  • 我在拉勾三个月的工作总结

    大家好,我是 myh0st ,目前我在拉勾网负责安全相关的工作,包括但不限于:安全建设、等保测评、渗透测试、安全培训等工作,目前我们所在是拉勾下面技术工程部运维...

    信安之路
  • 使用 SoapUI 测试ASP.NET Web API

    我们为不同的目的开发了很多web服务,经过授权的用户就可以访问和使用这些web服务。soapUI 是一个强大的测试web服务的工具,他不仅可以测试SOAP服务,...

    张善友
  • pytest文档47-allure报告添加用例失败截图

    使用 selenium 做 web 自动化的时候,很多小伙伴希望用例失败的时候能截图,把异常截图展示到allure报告里面。 pytest 有个很好的钩子函数 ...

    上海-悠悠
  • 吹弹牛皮之Unity 简易对象池(修订)

    曾在18年小菜去一家公司面试,在洽谈了约摸一个小时左右,面试官当即给出了一道上机操练的对象池笔试题目。题目内容大概是要求是:“每隔x秒随机产生10-20...

    用户7698595

扫码关注云+社区

领取腾讯云代金券