关于CSS重排和重绘的概念,最近看到不少这方面的文章,觉得挺有用,在制作中考虑浏览器的性能,减少重排能够节省浏览器对其子元素及父类元素的重新渲染;避免过分的重绘也能节省浏览器性能;优化动画,使用3D启用GPU硬件加速;慎重选择高消耗的样式,如box-shadow、border-radius、transform、css filters等。

浏览器的渲染机制

浏览器渲染展示网页的过程,大致分为以下几个步骤:

  1. 解析HTML(HTML Parser)
  2. 构建DOM树(DOM Tree)
  3. 渲染树构建(Render Tree)
  4. 绘制渲染树(Painting)

慎重选择高消耗的样式

什么 CSS 属性是高消耗的?就是那些绘制前需要浏览器进行大量计算的属性。

  • box-shadows
  • border-radius
  • transparency
  • transforms
  • CSS filters(性能杀手)

什么是reflow

浏览器为了重新渲染部分或整个页面,重新计算页面元素位置和几何结构的进程叫做reflow.

通俗点说就是当开发人员定义好了样式后(也包括浏览器的默认样式),浏览器根据这些来计算并根据结果将元素放到它应该出现的位置上,这个过程叫做reflow.

由于reflow是一种浏览器中的用户拦截操作,所以我们了解如何减少reflow次数,及DOM的层级,css效率对refolw次数的影响是十分有必要的。

reflow(回流)是导致DOM脚本执行效率低的关键因素之一,页面上任何一个节点触发了reflow,会导致它的子节点及祖先节点重新渲染。

简单解释一下 Reflow:当元素改变的时候,将会影响文档内容或结构,或元素位置,此过程称为 Reflow。

<body>
<div class="hello">
<h4>hello</h4>
<p><strong>Name:</strong>BDing</p>
<h5>male</h5>
<ol>
<li>coding</li>
<li>loving</li>
</ol>
</div>
</body>

当p节点上发生reflow时,hello和body也会重新渲染,甚至h5和ol都会收到影响。

什么时候会导致reflow发生呢?

  • 改变窗口大小
  • 改变文字大小
  • 添加/删除样式表
  • 内容的改变,(用户在输入框中写入内容也会)
  • 激活伪类,如:hover
  • 操作class属性
  • 脚本操作DOM
  • 计算offsetWidth和offsetHeight
  • 设置style属性
常见的重排元素      
width height padding margin
display border-width border top
position font-size float text-align
overflow-y font-weight overflow left
font-family line-height vertical-align right
clear white-space bottom min-height

减少reflow对性能的影响的建议

  1. 不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className
  2. 把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow),然后你修改100次,然后再把它显示出来
  3. 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量
  4. 尽可能不要修改影响范围比较大的 DOM
  5. 为动画的元素使用绝对定位 absolute / fixed
  6. 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局
  1. 尽可能限制reflow的影响范围,尽可能在低层级的DOM节点上,上述例子中,如果你要改变p的样式,class就不要加在div上,通过父元素去影响子元素不好。
  2. 避免设置大量的style属性,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow,所以最好是使用class属性
  3. 实现元素的动画,它的position属性,最好是设为absoulte或fixed,这样不会影响其他元素的布局
  4. 动画实现的速度的选择。比如实现一个动画,以1个像素为单位移动这样最平滑,但是reflow就会过于频繁,大量消耗CPU资源,如果以3个像素为单位移动则会好很多。
  5. 不要使用table布局,因为table中某个元素旦触发了reflow,那么整个table的元素都会触发reflow。那么在不得已使用table的场合,可以设置table-layout:auto;或者是table-layout:fixed这样可以让table一行一行的渲染,这种做法也是为了限制reflow的影响范围
  6. 如果CSS里面有计算表达式,每次都会重新计算一遍,出发一次reflow

什么是repaint

repaint是在一个元素的外观被改变,但没有改变布局的情况下发生的,如改变了visibility、outline、background等。当repaint发生时,浏览器会验证DOM树上所有其他节点的visibility属性。

通俗来说,就是当各种盒子的位置、大小以及其他属性,例如颜色、字体都确定下来后,浏览器便把这些元素都按照各自的特性绘制一遍,于是页面的内容出现了,这个过程叫做repaint

避免过分重绘(Repaints)

当元素改变的时候,将不会影响元素在页面当中的位置(比如 background-colorborder-colorvisibility),浏览器仅仅会应用新的样式重绘此元素,此过程称为 Repaint

常见的重绘元素      
color border-style visibility background
text-decoration background-image background-position background-repeat
outline-color outline outline-style border-radius
outline-width box-shadow background-size

优化动画

css3 动画是优化的重中之重。除了做到上面两点,减少 Reflow 和 Repaints 之外,还需要注意以下方面。

启用 GPU 硬件加速

GPU(Graphics Processing Unit) 是图像处理器GPU 硬件加速是指应用 GPU 的图形性能对浏览器中的一些图形操作交给 GPU 来完成,因为 GPU 是专门为处理图形而设计,所以它在速度和能耗上更有效率。
GPU 加速可以不仅应用于3D,而且也可以应用于2D。这里, GPU 加速通常包括以下几个部分:Canvas2D布局合成(Layout Compositing)CSS3转换(transitions)CSS3 3D变换(transforms)WebGL视频(video)

/*
* 根据上面的结论
* 将 2d transform 换成 3d
* 就可以强制开启 GPU 加速
* 提高动画性能
*/
div {
transform: translate(10px, 10px);
}
div {
transform: translate3d(10px, 10px, 0);
}

需要注意的是,开启硬件加速相应的也会有额外的开销,参见这篇文章 CSS 硬件加速的好与坏

优化CSS重排重绘与浏览器性能的更多相关文章

  1. 页面优化,谈谈重绘(repaint)和回流(reflow)

    一.前言 偶尔在面试过程中遇到过重汇与回流reflow的问题,毕竟页面优化也是考核一个开发者能力的关键之一,上篇文章聊了下documentfragment也是为了减轻回流问题,那么本篇文章好好介绍下重 ...

  2. 图层 & 重排 & 重绘

    图层 浏览器在渲染一个页面时,会将页面分为很多个图层,图层有大有小,每个图层上有一个或多个节点 渲染 DOM 时 浏览器所做的: 获取 DOM 后分割为多个图层 对每个图层的节点计算样式结果 (Rec ...

  3. 前端性能优化--为什么DOM操作慢? 浅谈DOM的操作以及性能优化问题-重绘重排 为什么要减少DOM操作 为什么要减少操作DOM

    前端性能优化--为什么DOM操作慢?   作为一个前端,不能不考虑性能问题.对于大多数前端来说,性能优化的方法可能包括以下这些: 减少HTTP请求(合并css.js,雪碧图/base64图片) 压缩( ...

  4. 关于DOM的操作以及性能优化问题-重绘重排

     写在前面: 大家都知道DOM的操作很昂贵. 然后贵在什么地方呢? 一.访问DOM元素 二.修改DOM引起的重绘重排 一.访问DOM 像书上的比喻:把DOM和JavaScript(这里指ECMScri ...

  5. css 重排与重绘

    css 重绘与重排 我们要知道当浏览器下载完页面的所有资源后,就会开始解析源代码. HTML 会被解析成 DOM Tree,Css 则会被渲染成 CSSOM Tree,最后它们会附加到一起,形成渲染树 ...

  6. 高性能JavaScript 重排与重绘

    先回顾下前文高性能JavaScript DOM编程,主要提了两点优化,一是尽量减少DOM的访问,而把运算放在ECMAScript这一端,二是尽量缓存局部变量,比如length等等,最后介绍了两个新的A ...

  7. 【笔记】web 的回流与重绘及优化

    最近看了幕课网 web 前端性能优化的课程,其中说到了浏览器的回流(reflow) 及 重绘(repaint).觉得以后面试或许会被问到所以做一下笔记: 课程从回流及重绘这两个点延伸出了一个知识点就是 ...

  8. 高性能WEB开发:重排与重绘

    DOM编程可能最耗时的地方,重排和重绘. 1.什么是重排和重绘 浏览器下载完页面中的所有组件——HTML标记.JavaScript.CSS.图片之后会解析生成两个内部数据结构——DOM树和渲染树. D ...

  9. js 重排和重绘

    1.什么是重排和重绘 浏览器下载完页面中的所有组件--HTML标记.JavaScript.CSS.图片之后会解析生成两个内部数据结构--DOM树和渲染树. DOM树表示页面结构,渲染树表示DOM节点如 ...

随机推荐

  1. C#反射の反射泛型

    C#反射の反射详解(点击跳转)C#反射の反射接口(点击跳转)C#反射反射泛型接口(点击跳转)C#反射の一个泛型反射实现的网络请求框架(点击跳转) 接上篇. 自定义一个泛型类(继承于接口) public ...

  2. php面试题整理(四)

    应该是group by username }

  3. Google Colab 基本操作

    ## 上传 from google.colab import files uploaded = files.upload() for fn in uploaded.keys(): print('Use ...

  4. springboot 服务工程,前端服务调用接口报跨域错误

    前后端分离,VUE.JS调用服务接口时,跨域错误.需要服务接口工程设置,如下: @SpringBootApplicationpublic class SpringCloudOpenapiApplica ...

  5. 【转】iOS弹幕库OCBarrage-如何hold住每秒5000条巨量弹幕

    最近公司做新需求, 原来用的老弹幕库, 已经无法满足需要. 迫不得已自己写了一套弹幕库OCBarrage. 这套弹幕库轻量, 可拓展, 高度自定义, 超高性能, 简单易上手. 无论哪家公司软件的性能绝 ...

  6. 缓存表 内存表(将表keep到内存)

    缓存表 内存表(将表keep到内存) 一.引言:     有时候一些基础表需要非常的频繁访问,尤其是在一些循环中,对该表中的访问速度将变的非常重要.为了提高系统的处理性能,可以考虑将一些表及索引读取并 ...

  7. Java多线程(四)—— synchronized关键字续

    1.synchronized原理 在java中,每一个对象有且仅有一个同步锁.这也意味着,同步锁是依赖于对象而存在.当我们调用某对象的synchronized方法时,就获取了该对象的同步锁.例如,sy ...

  8. vue-cli sass安装

    一.安装对应依赖node模块: npm install node-sass --save-dev npm install sass-loader --save-dev 二.打开webpack.base ...

  9. RabbitMQ详解(一)------简介与安装

    RabbitMQ 这个消息中间件,其实公司最近的项目中有用到,但是一直没有系统的整理,最近看完了<RabbitMQ实战  高效部署分布式消息队列>这本书,所以顺便写写. 那么关于 Rabb ...

  10. 如何备份和恢复你的TFS服务器(二)

    配置一个备份计划 在你的TFS(Team Foundation Server)2010服务器上安装新版本的Power Tools以后(是的,这个工具只支持TFS(Team Foundation Ser ...