最近看了幕课网 web 前端性能优化的课程,其中说到了浏览器的回流(reflow) 及 重绘(repaint)。觉得以后面试或许会被问到所以做一下笔记:

课程从回流及重绘这两个点延伸出了一个知识点就是 "css 会影响 javascrip 执行时间导致 javascript 脚本变慢"。

浏览器渲染一个网页的时候会启用两条线程:一条渲染javascript 脚本,另一条渲染 ui 即css 样式的渲染。但这两条线程是互斥的。当javascript 线程运行的时候 ui 线程则会中止暂停,反之亦然。

那这是为什么呢?

原因是,当ui 线程运行对页面进行渲染的时候 js 脚本难免会设计到页面视图上的一些样式的改变,为了使这个改变更加准确 js 脚本只好等待ui 线程渲染完成的时候才去执行。

所以当一个页面的元素样式改动频繁的时候ui 线程就会持续渲染,造成js 代码反应慢半拍,卡顿的情况。

那回流和重绘究竟是什么呢?为什么他们的威力会那么大呢?

回流:当render tree 的一部分或全部的元素因改变了自身的宽高,布局,显示或隐藏,或者元素内部的文字结构发生变化 导致需要重新构建页面的时候,回流就产生了

重绘:当一个元素自身的宽高,布局,及显示或隐藏没有改变,而只是改变了元素的外观风格的时候,就会产生重绘。例如你改变了元素的background-color....

因此得出了一个结论:

回流必定触发重绘,而重绘不一定触发回流

触发回流的css 属性有这些:

而触发重绘的有这些:

现在我们知道了那些属性会触发回流,那如何避免回流呢?

其实有两个方法:第一,不使用以上能触发图层回流的属性,第二,建立一个图层,让回流在这些图层里面进行,不会扩展到整个页面

先说说图层吧

css 中有一个重要的概念的就是 "划分图层"。

在页面加载完dom之后,浏览器会根据自身制定的一些特殊css 属性对页面进行划分为一个个图层。例如:一些有着 position: absolute 属性的元素他们会被浏览器归纳到一个图层中,而另外一些 position: fixed 的元素也会被浏览器归纳到另外一个图层中,还有一些例如:transform: translateZ(0)....这些属性都是视浏览器厂商制定的

图层的优点就是:当一个元素在自己图层内发生变化的时候它的回流和重绘只会在图层内部发生,而不会影响到整个页面。

那图层内部究竟干了什么呢?

首先,图层对图层里面的节点做回流和重布局运算,计算出他们的样式

然后,对它们生成图形和位置

紧跟着,将每个节点绘制填充到图层位图中

再然后,图层作为纹理发送到GPU 上

最后,将所有图层合并,显示在浏览器的页面上

图层虽好,但是如果滥用图层的话就会让页面因为进行太多图层合并导致卡顿。

所以说,图层的用途应该让给那些经常要进行位置结构,布局变换的元素去使用。例如轮播图

那我们如创建一个图层呢?

就拿chrome 来说,创建一个图层要有以下其中一个条件:

1:一个dom 元素拥有 3d 或 透视变换的css 属性(persepective, transform)

2:video 标签

3:拥有3d 上下文或加速 2d 上下文的 canvas 节点

4:混合插件 flash

5:自己做的opacity 动画 或 使用一个动画 webkit 变换的元素

6:拥有 translate3d 或 translateZ 这两会使 GPU 加速的属性

7:一个包含复合层子节点的元素。(有点绕,可以这样想:其实本身整个网页页面就是一个图层,html 标签下包含着若干的标签 head, body,..... 这样便满足了这个条件了)

8:元素有一个其 z-index 比它低的兄弟节点。由于 z-index 控制的是元素上下层的关系,所以当上下层关系变换的时候就需要一个图层去渲染,因此满足这个条件的元素也会被创建一个图层

但是在我的实验中发现第7 和 8是没有被变成图层的,不知道为嘛.......

那如果我们使用属性又有那些可替换的属性可以优化回流与重绘呢,一共有一下5点:

1:用transform 代替 top,left ,margin-top, margin-left... 这些位移属性

2:用opacity 代替 visibility,但是要同时有translate3d 或 translateZ 这些可以创建的图层的属性存在才可以阻止回流

但是第二点经过我的实验,发现如果不加 transform: translateZ(0) 配合opacity的话还是会产生回流的,而只用visibility 就只会产生重绘不会回流

而  opacity 加上 transform: translateZ/3d  这个属性之后便不会发生回流和重绘了

3:不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。

4:如果确实需要用 js 对 dom 设置多条样式那么可以将这个dom 先隐藏,然后再对其设置

5:不要在循环内获取dom 的样式例如:offsetWidth, offsetHeight, clientWidth, clientHeight... 这些。浏览器有一个回流的缓冲机制,即多个回流会保存在一个栈里面,当这个栈满了浏览器便会一次性触发所有样式的更改且刷新这个栈。但是如果你多次获取这些元素的实际样式,浏览器为了给你一个准确的答案便会不停刷新这个缓冲栈,导致页面回流增加。

所以为了避免这个问题,应该用一个变量保存在循环体外。

6:不要使用table 布局,因为table 的每一个行甚至每一个单元格的样式更新都会导致整个table 重新布局

7:动画的速度按照业务按需决定

8:对于频繁变化的元素应该为其加一个 transform 属性,对于视频使用video 标签

9:必要时可以开启 GPU 加速,但是不能滥用

【笔记】web 的回流与重绘及优化的更多相关文章

  1. JS学习笔记:(二)回流和重绘

    在搞清楚回流和重绘的概念之前,我们要清除浏览器的渲染过程. 解析生成DOM Tree(此时包含所有节点,包括display:none); 根据CSS Object Module(CCSSOM)计算节点 ...

  2. 【JS】313- 复习 回流和重绘

    点击上方"前端自习课"关注,学习起来~ 原文地址:我不是陈纪庚 segmentfault.com/a/1190000017329980 回流和重绘可以说是每一个web开发者都经常听 ...

  3. 什么是回流(重排 reflow)?什么是重绘(repaint)?如何减少回流、重绘?

    什么是回流(重排 reflow)? 回流(重排 reflow):对DOM树进行渲染,只要修改DOM或修改元素的形状大小,就会触发reflow,reflow的时候,浏览器会使已渲染好受到影响的部分失效, ...

  4. DOM的回流和重绘(重排、重绘)

    什么是DOM回流? 页面渲染时,我们对HTML结构简单的增删查改时,浏览器会对所有的dom进行重新排序,这就i是DOM回流,严重影响浏览器性能 DOM的回流和重绘: **DOM的回流**:当页面中元素 ...

  5. 浏览器的回流与重绘 (Reflow & Repaint)

    写在前面 在讨论回流与重绘之前,我们要知道: 浏览器使用流式布局模型 (Flow Based Layout). 浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了 ...

  6. 介绍回流与重绘(Reflow & Repaint),以及如何进行优化?

    前言 回流与重绘对于前端来说可以说是非常重要的知识点了,我们不仅需要知道什么是回流与重绘,还需要知道如何进行优化.一个页面从加载到完成,首先是构建DOM树,然后根据DOM节点的几何属性形成render ...

  7. 回流与重绘:CSS性能让JavaScript变慢?

    参考张鑫旭博客: http://www.zhangxinxu.com/wordpress/2010/01/%E5%9B%9E%E6%B5%81%E4%B8%8E%E9%87%8D%E7%BB%98%E ...

  8. 【web性能】页面呈现、重绘、回流

    在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...

  9. 高性能WEB开发:深入理解页面呈现、重绘、回流

    在讨论页面重绘.回流之前.需要对页面的呈现流程有些了解,页面是怎么把html结合css等显示到浏览器上的,下面的流程图显示了浏览器对页面的呈现的处理流程.可能不同的浏览器略微会有些不同.但基本上都是类 ...

随机推荐

  1. jscodeshift 简易教程

    本文首发于 https://github.com/whxaxes/blog/issues/10 背景 jscodeshift 是 fb 出的一个 codemod toolkit,基于 recast 这 ...

  2. win10 uwp 按下等待按钮

    我们经常需要一个按钮,在按下时,后台执行Task,这时不能再次按下按钮. 我们使用自定义控件,首先新建一个类,我把它命名是ProgressButton 一个进度条按钮,也就是我们按下时发生进度条,完成 ...

  3. word2vec 在 非 自然语言处理 (NLP) 领域的应用

    word2vec 本来就是用来解决自然语言处理问题的,它在 NLP 中的应用是显然的. 比如,你可以直接用它来寻找相关词.发现新词.命名实体识别.信息索引.情感分析等:你也可以将词向量作为其他模型的输 ...

  4. [extjs(2)] extjs第一个组件treepanel

    刚刚在接触extjs这个前段插件,由于公司是用这个来做前段的,所以有必要花点时间来掌握一下,下面是我自己的非常浅的学习总结,后期会慢慢添加的!! 一.TreePanel基本配置参数: animate: ...

  5. web项目生成war包的问题

    今天面试一家公司,问我生成war包的命令是什么? 当时没明白,就说自己用的eclipse直接右键 export --->war 完了重启tomcat(第一种) 好久没用maven了.回来一查才明 ...

  6. 分布式学习(一)——基于ZooKeeper的队列爬虫

    zookeeper 一直琢磨着分布式的东西怎么搞,公司也没有相关的项目能够参与,所以还是回归自己的专长来吧--基于ZooKeeper的分布式队列爬虫,由于没什么人能够一起沟通分布式的相关知识,下面的小 ...

  7. 从入门到放弃之IO

    浅说IO 学到现在利用过的特殊符号不少组合起来很多都有让人眼前一亮的用法,在这里先聊聊I/O的一些相关知识. 本文开始之前先介绍一下需要知道的一些小知识和需要注意的地方. 在linux中也是有优先级的 ...

  8. #1094 : Lost in the City by C solution

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi gets lost in the city. He does not know where he is ...

  9. JavaScript--我发现,原来你是这样的JS:面向对象编程OOP[1]--(理解对象和对象属性类型)

    一.介绍 老铁们,这次是JS的面向对象的编程OOP(虽然我没有对象,心累啊,但是可以自己创建啊,哈哈). JS高程里第六章的内容,这章内容在我看来是JS中很难理解的一部分.所以分成三篇博客来逐个理清. ...

  10. Surround the Trees(凸包)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...