JavaScript中的Repaint和Reflow用法详解


Posted in Javascript onJuly 27, 2015

你是不是经常听师兄或一些前端前辈说不能用CSS通配符 *,CSS选择器层叠不能超过三层,CSS尽量使用类选择器,书写HTML少使用table,结构要尽量简单-DOM树要小....等这些忠告,以前我就大概知道使用通配符或者CSS选择器层次过多可能会降低性能,至于为什么不使用table标签我一直是迷迷糊糊,也就跟着那样做了,但我认识了Repain和 Reflow之后,原来这些还真不能用太多。 ok,希望这篇文章对你有帮助!

1.什么是Repaint/Reflow?

好,先上一张图:浏览器解析大概的工作流程

JavaScript中的Repaint和Reflow用法详解

这张图应该可以很好理解,归纳为四个步骤:

1、解析HTML以构建DOM树:渲染引擎开始解析HTML文档,转换树中的html标签或js生成的标签到DOM节点,它被称为 -- 内容树。
2、构建渲染树:解析CSS(包括外部CSS文件和样式元素以及js生成的样式),根据CSS选择器计算出节点的样式,创建另一个树 —- 渲染树。
3、布局渲染树: 从根节点递归调用,计算每一个元素的大小、位置等,给每个节点所应该出现在屏幕上的精确坐标。
4、绘制渲染树: 遍历渲染树,每个节点将使用UI后端层来绘制。

好,我们可以看到Repain 和 Reflow 分别出现在了第三和第四步。因此我们给出下面的定义:

    对于DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式(浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow;当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint。
    可见这两个东东对浏览器渲染页面是很重要的啊,都是会影响性能的,因此我们需要了解一些常见的会引起repaint和reflow的一些操作,并且应该尽量减少以提高渲染速度。

2.引起Repain和Reflow的一些操作

Reflow 的成本比 Repaint 的成本高得多的多。DOM Tree 里的每个结点都会有 reflow 方法,一个结点的 reflow 很有可能导致子结点,甚至父点以及同级结点的 reflow。在一些高性能的电脑上也许还没什么,但是如果 reflow 发生在手机上,那么这个过程是非常痛苦和耗电的。
所以,下面这些动作有很大可能会是成本比较高的。

  •     当你增加、删除、修改 DOM 结点时,会导致 Reflow 或 Repaint。
  •     当你移动 DOM 的位置,或是搞个动画的时候。
  •     当你修改 CSS 样式的时候。
  •     当你 Resize 窗口的时候(移动端没有这个问题),或是滚动的时候。
  •     当你修改网页的默认字体时。

注:display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。
3.如何优化?

Reflow是不可避免的,只能将Reflow对性能的影响减到最小,给出下面几条建议:

    不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,然后修改 DOM 的 className:

   

// 不好的写法
  var left = 10,
  top = 10;
  el.style.left = left + "px";
  el.style.top = top + "px";
  // 推荐写法
  el.className += " theclassname";

    把 DOM 离线后修改。如:
    a> 使用 documentFragment 对象在内存里操作 DOM。
    b> 先把 DOM 给 display:none (有一次 repaint),然后你想怎么改就怎么改。比如修改 100 次,然后再把他显示出来。
    c> clone 一个 DOM 节点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。

    不要把 DOM 节点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性。

    尽可能的修改层级比较低的 DOM节点。当然,改变层级比较底的 DOM节点有可能会造成大面积的 reflow,但是也可能影响范围很小。

    为动画的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是会大大减小 reflow 。

    千万不要使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。

认识了这些是不是对浏览器的原理有更大兴趣了?OK,后面会更新关于浏览器原理的文章,或者你们可以先去搜搜别人的,因为我觉得理解浏览器的原理确实是很重要,可以帮助我们写出性能更好的website。

Javascript 相关文章推荐
jQuery代码优化 遍历篇
Nov 01 Javascript
jQuery带箭头提示框tooltips插件集锦
Nov 17 Javascript
使用jquery制作弹出框效果
Apr 03 Javascript
JavaScript中字符串拼接的基本方法
Jul 07 Javascript
javascript实现类似于新浪微博搜索框弹出效果的方法
Jul 27 Javascript
用javascript实现自动输出网页文本
Jul 30 Javascript
jquery实现移动端点击图片查看大图特效
Sep 11 Javascript
深入讲解xhr(XMLHttpRequest)/jsonp请求之abort
Jul 26 Javascript
利用ES6的Promise.all实现至少请求多长时间的实例
Aug 28 Javascript
ionic2懒加载配置详解
Sep 01 Javascript
jQuery单页面文字搜索插件jquery.fullsearch.js的使用方法
Feb 04 jQuery
Vue Element UI自定义描述列表组件
May 18 Vue.js
javascript实现类似java中getClass()得到对象类名的方法
Jul 27 #Javascript
AngularJS的一些基本样式初窥
Jul 27 #Javascript
javascript实现网页子页面遍历回调的方法(涉及 window.frames、递归函数、函数上下文)
Jul 27 #Javascript
JavaScript数组对象实现增加一个返回随机元素的方法
Jul 27 #Javascript
使用HTML+CSS+JS制作简单的网页菜单界面
Jul 27 #Javascript
Javascript验证Visa和MasterCard信用卡号的方法
Jul 27 #Javascript
JavaScript实现自动对页面上敏感词进行屏蔽的方法
Jul 27 #Javascript
You might like
在服务端进行目录建立、删除,文件上传、删除的过程的php代码
2008/09/10 PHP
php self,$this,const,static,->的使用
2009/10/22 PHP
php curl抓取网页的介绍和推广及使用CURL抓取淘宝页面集成方法
2015/11/30 PHP
解决tp5在nginx下修改配置访问的问题
2019/10/16 PHP
JavaScript对象模型-执行模型
2008/04/28 Javascript
innerText和textContent对比及使用介绍
2013/02/27 Javascript
javascript中的void运算符语法及使用介绍
2013/03/10 Javascript
JS 删除字符串最后一个字符的实现代码
2014/02/20 Javascript
javascript中call,apply,bind的用法对比分析
2015/02/12 Javascript
用JavaScript动态建立或增加CSS样式表的实现方法
2016/05/20 Javascript
更靠谱的H5横竖屏检测方法(js代码)
2016/09/13 Javascript
什么是JavaScript中的结果值?
2016/10/08 Javascript
探索Vue.js component内容实现
2016/11/03 Javascript
jquery平滑滚动到顶部插件使用详解
2017/05/08 jQuery
详解vue-cli本地环境API代理设置和解决跨域
2017/09/05 Javascript
javascript基本常用排序算法解析
2017/09/27 Javascript
vue 将页面公用的头部组件化的方法
2017/12/18 Javascript
Vue波纹按钮组件制作
2018/04/30 Javascript
Js 利用正则表达式和replace函数获取string中所有被匹配到的文本(推荐)
2018/10/28 Javascript
Vue利用History记录上一页面的数据方法实例
2018/11/02 Javascript
inquirer.js一个用户与命令行交互的工具详解
2019/05/18 Javascript
Python实现可自定义大小的截屏功能
2018/01/20 Python
解决python中无法自动补全代码的问题
2018/12/04 Python
django用户登录验证的完整示例代码
2019/07/21 Python
如何基于python生成list的所有的子集
2019/11/11 Python
Python3.7 读取音频根据文件名生成脚本的代码
2020/04/07 Python
美国第二大团购网站:LivingSocial
2016/07/24 全球购物
英国一家集合了众多有才华设计师品牌的奢侈店:Wolf & Badger
2018/04/18 全球购物
联想智利官方网站:Lenovo Chile
2020/06/03 全球购物
艺术系应届生的自我评价
2013/10/19 职场文书
期末个人总结范文
2015/02/13 职场文书
2015年七一建党节慰问信
2015/03/23 职场文书
晚会主持人开场白台词
2015/05/28 职场文书
现实表现证明材料
2015/06/19 职场文书
运动会跳远广播稿
2015/08/19 职场文书
React-vscode使用jsx语法的问题及解决方法
2021/06/21 Javascript