在前面小节,我们对网页渲染过程做了介绍,其中最后两步就是layout与paint,当渲染对象被创建并添加到树中,它们并没有位置和大小,计算这些值的过程称为layout或reflow。绘制阶段,遍历渲染树并调用渲染对象的paint方法将它们的内容显示在屏幕上,绘制使用UI基础组件。

何时发生?

由两者的定义我们可以知道在元素的大小和位置发生变化时都会触发reflow,且也会引起repaint,当元素的位置和大小没有变化,如改变背景颜色等等,只会进行重新repaint,如修改opacitybackground-colorvisibilityoutline等。

reflow比repaint开销更大,修改一个元素的大小或位置会影响它的子节点,父节点,兄弟节点甚至是整个文档。例如修改页面字体大小,将会导致整个文档reflow,在body最前面添加一个元素会导致后面所有元素reflow。

具体来说:

  • 添加、删除元素
  • 更改元素的display:none或显示引起reflow
  • 增加或删除元素style规则,不同规则影响不同,如修改width会引起reflow
  • 移动元素位置
  • CSS3动画,每一帧都会引起reflow(可能有硬件加速)
  • 用户行为如改变浏览器字体大小、改变窗口大小、在输入框输入文字、触发:hover等等

浏览器优化策略

  • 采用Dirty bit系统,只针对具有dirty标记的元素进行重新layout,即增量layout,且此过程是异步的.
  • Firefox为增量layout生成了reflow队列,以及一个调度执行这些批处理命令。Webkit也有一个计时器用来执行增量layout-遍历树,为dirty状态的渲染对象重新布局。意思是会将多个reflow操作汇集到一定数量后再一起处理,减轻压力
  • 如果元素只是位置发生变化,其大小从缓存里读取,就不用再次计算

针对上面的reflow队列,当访问以下style属性时,浏览器为了给你最精确的值,需要flush队列,因为队列中可能会有影响到这些值的操作:

  • offsetTop, offsetLeft, offsetWidth, offsetHeight
  • scrollTop/Left/Width/Height
  • clientTop/Left/Width/Height
  • width,height
  • 请求了getComputedStyle(), 或者 ie的 currentStyle

减少reflow和repaint

布局技术最佳实践

  • 少使用内联样式
  • 表格数据使用:table-layout: fixed
  • flexbox布局可能带来性能问题

减少样式规则

许多时候我们在页面上引入的规则很多并没有用到,例如使用bootstrap等,除了按需引入外,我们还可以通过一些自动化工具去除页面中没有使用到的规则。如gulp-uncss:

var gulp = require('gulp');
var postcss = require('gulp-postcss');
var uncss = require('postcss-uncss'); gulp.task('default', function () {
var plugins = [
uncss({
html: ['index.html', 'posts/**/*.html', 'http://example.com']
}),
];
return gulp.src('./src/*.css')
.pipe(postcss(plugins))
.pipe(gulp.dest('./dest'));
});

详情参考文档:https://github.com/ben-eb/gulp-uncss

减少DOM树嵌套层次

减少不必要的嵌套层可以加快reflow过程。

批量操作

如果以下面的方式更新元素:

var myelement = document.getElementById('myelement');
myelement.width = '100px';
myelement.height = '200px';
myelement.style.margin = '10px';

会造成三次reflow(不考虑浏览器优化)

改善方式是通过改变元素的class属性来应用样式表里不同规则:

var myelement = document.getElementById('myelement');
myelement.classList.add('newstyles');
.newstyles {
width: 100px;
height: 200px;
margin: 10px;
}

或者直接修改cssText:

myelement.cssText += 'width:100px;height:200px;margin:10px';

离线操作

  • 使用createDocumentFragment()等创建节点,再将其他所有节点加入其子节点,最后才加入到真实DOM里去
  • 先将元素设置为隐藏即:display:none,做一系列更改后再显示回来

减少访问会引起flush的属性

尽量减少访问上面提到的一系列会引起reflow队列flush的属性,如果要多次访问,最好设置缓存变量。

使进行复杂动画的元素脱离文档流

通过设置动画元素position: absolute; 或者 position: fixed;可以使元素脱离文档流来避免在动画的过程中影响其他元素。

// block1是position:absolute 定位的元素,它移动会影响到它父元素下的所有子元素。
// 因为在它移动过程中,所有子元素需要判断block1的z-index是否在自己的上面,
// 如果是在自己的上面,则需要重绘,这里不会引起回流
$("#block1").animate({left:50});
// block2是相对定位的元素,这个影响的元素与block1一样,但是因为block2非绝对定位
// 而且改变的是marginLeft属性,所以这里每次改变不但会影响重绘,
// 还会引起父元素及其下元素的回流
$("#block2").animate({marginLeft:50});

动画平滑度

动画每一帧元素移动1个像素和4个像素平滑程度比起来,两者平滑程度感受起来差别不大,但是后者会大大减少reflow次数。

动画硬件加速

// todo

参考

https://www.sitepoint.com/10-ways-minimize-reflows-improve-performance/

http://www.blogjava.net/BearRui/archive/2010/05/10/web_performance_repaint_relow.html

https://github.com/laoqiren/web-performance/blob/master/%E7%BD%91%E9%A1%B5%E6%B8%B2%E6%9F%93%E5%8E%9F%E7%90%86/repaint%E4%B8%8Ereflow.md

前段性能----repaint和reflow的更多相关文章

  1. javascript性能优化-repaint和reflow

    repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲 ...

  2. css的repaint和reflow

    css的repaint和reflow 浏览器为了重新渲染部分或整个页面,重新计算页面元素位置和几何结构(geometries)的进程叫做 reflow. 由于 reflow 是一种浏览器中的用户拦截( ...

  3. 探讨css中repaint和reflow

    (个人blog迁移文章.) 前言: 页面设计中,不可避免的需要浏览器进行repaint和reflow.那到底什么是repaint和reflow呢.下面谈谈自己对repaint和reflow的理解,以及 ...

  4. [ JS 进阶 ] Repaint 、Reflow 的基本认识和优化

    你是不是经常听师兄或一些前端前辈说不能用CSS通配符 *,CSS选择器层叠不能超过三层,CSS尽量使用类选择器,书写HTML少使用table,结构要尽量简单-DOM树要小....等这些忠告,以前我就大 ...

  5. repaint和reflow的相关知识

    一个页面由两部分组成: DOM:描述该页面的结构 render渲染:描述 DOM 节点 (nodes) 在页面上如何呈现 repaint重绘: 当 DOM 元素的属性发生变化 (如 color) 时, ...

  6. 【转】javascript性能优化-repaint和reflow

    repaint(重绘) ,repaint发生更改时,元素的外观被改变,且在没有改变布局的情况下发生,如改变outline,visibility,background color,不会影响到dom结构渲 ...

  7. 性能优化之reflow和repaint

    本文主要介绍一下什么是reflow,repaint, 怎样避免它们造成的不良影响, 怎么通过工具查看分析它们. 一.首先对浏览器渲染引擎下网页呈现过程简要说一下: 浏览器的渲染引擎开始解析html构建 ...

  8. 前端性能优化-减少http请求,dns预解析,减少repaint和reflow

    前端性能优化方法: 一 . 减少http请求 (1)通过合并图片,减少请求,俗称css sprites(css精灵)css sprites (2)lazyload懒加载,在需要的时候再加载 1.定义: ...

  9. 前端性能优化--回流(reflow)和重绘(repaint)

    HTML加载时发生了什么 在页面加载时,浏览器把获取到的HTML代码解析成1个DOM树,DOM树里包含了所有HTML标签,包括display:none隐藏,还有用JS动态添加的元素等. 浏览器把所有样 ...

随机推荐

  1. sts问题合集

    背景:用来记录在使用sts过程中遇到的相关问题 Version 当前jdk版本号 of the JVM is not suitable for the this product.Version:1.8 ...

  2. [转帖]知新之--12-factors

    知新之--12-factors https://blog.csdn.net/weixin_34233421/article/details/85819756 12-factors I. 基准代码 一份 ...

  3. Python Web 之 Flask SQLalchemy

    Flask-SQLalchemy 一. 一对多 A表中的一条记录与B表中的多天记录关联 语法实现: 在"多"实体类中增加 外键列名 = db.Column(db.Integer, ...

  4. 认清楚服务器的真正身份--深入ARP工作原理

    我们知道IP地址是ISP分配给我们的,IP不能作为服务器的唯一的身份,那么服务器真正的身份是什么呢?MAC IP地址直接的通信在底层要转换到MAC直接的通信,那他们如何通信的呢? 1.简介 出场人物: ...

  5. VS web停止调试后关闭浏览器

  6. 关于win server中 task Scheduler使用

    日常开发过程中最会遇到很多定时任务,利用计算机自带的软件工具,既方便,又快捷,能节省大量的开发时间,而且功能全面,容错率高. 下面举个例子:定时发送邮件,每天8:10准时触发邮件发送脚本 1.首先配置 ...

  7. 阿里云RDS数据库sql server 导入数据并添加作业小结

    在阿里云购买ECS服务器和RDS数据库时,要注意网络类型要一致,最好都是VPC,否则ECS不能在内网访问RDS,只能从外网访问:在RDS控制台左侧,数据库安全性的IP白名单中添加ECS外网IP:在数据 ...

  8. SecureCRT上传本地文件到linux

    1.使用crt登录到需要操作的linux系统 2.按Alt+P打开sftp传输界面 3.输入pur指令加文件路径,例如:put E://srs-3.0.zip按enter就可以 4.再返回crt界面, ...

  9. VMwarm下安装ubuntu的一些问题

    1.终端无法输入中文的原因(未实践)  原文地址 2.Windows10下VMwarm(V15.5)和ubuntu14.04实现复制文件(已经实践)  转载路径

  10. ASP.NET Core 2.0升级到3.0的变化和问题

    前言 在.NET Core 2.0发布的时候,博主也趁热使用ASP.NET Core 2.0写了一个独立的博客网站,现如今恰逢.NET Core 3.0发布之际,于是将该网站进行了升级. 下面就记录升 ...