其他分享
首页 > 其他分享> > 性能测试----repaint和reflow

性能测试----repaint和reflow

作者:互联网

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

何时发生?

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

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

具体来说:

 

浏览器优化策略

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

 

减少reflow和repaint

布局技术最佳实践

减少样式规则

许多时候我们在页面上引入的规则很多并没有用到,例如使用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';

离线操作

减少访问会引起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,layout,reflow,元素,gulp,测试,myelement
来源: https://www.cnblogs.com/syw20170419/p/11991500.html