美文网首页前端技术Web前端之路让前端飞
网页性能管理:重绘和重排

网页性能管理:重绘和重排

作者: 葶寳寳 | 来源:发表于2017-08-18 21:56 被阅读108次

网页生成的过程

要理解网页性能为什么不好,就要了解网页是怎么生成的。

网页的生成过程,大致可以分成五步:
1.HTML代码转化成DOM
2.CSS代码转化成CSSOMCSS Object Model)。
3.结合DOMCSSOM,生成一棵渲染树(包含每个节点的视觉信息)。
4.生成布局(layout),即将所有渲染树的所有节点进行平面合成。
5.将布局绘制(paint)在屏幕上。

"生成布局"(flow)和"绘制"(paint)这两步,合称为"渲染"(render)。

重排和重绘

网页生成的时候,至少会渲染一次。用户访问的过程中,还会不断重新渲染。

重新渲染,就需要重新生成布局和重新绘制。前者叫做重排(reflow),后者叫做重绘(repaint)。

需要注意的是,重绘不一定需要重排重排必然导致重绘

对于性能的影响

提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。

DOM变动和样式变动,都会触发重新渲染。但是,浏览器已经很智能了,会尽量把所有的变动集中在一起,排成一个队列,然后一次性执行,尽量避免多次重新渲染。

div.style.color = 'blue';
div.style.marginTop = '30px';

上面代码中,div元素有两个样式变动,但是浏览器只会触发一次重排和重绘。

如果写得不好,就会触发两次重排和重绘。

div.style.color = 'blue';
var margin = parseInt(div.style.marginTop);
div.style.marginTop = (margin + 10) + 'px';

上面代码对div元素设置背景色以后,第二行要求浏览器给出该元素的位置,所以浏览器不得不立即重排。

一般来说,样式的写操作之后,如果有下面这些属性的读操作,都会引发浏览器立即重新渲染。

offsetTop/offsetLeft/offsetWidth/offsetHeight
scrollTop/scrollLeft/scrollWidth/scrollHeight
clientTop/clientLeft/clientWidth/clientHeight
getComputedStyle()

所以,从性能角度考虑,尽量不要把读操作和写操作,放在一个语句里面。

// bad
div.style.left = div.offsetLeft + 10 + "px";
div.style.top = div.offsetTop + 10 + "px";

// good
var left = div.offsetLeft;
var top  = div.offsetTop;
div.style.left = left + 10 + "px";
div.style.top = top + 10 + "px";

一般的规则是:

  • 样式表越简单,重排和重绘就越快。
  • 重排和重绘的DOM元素层级越高,成本就越高。
  • table元素的重排和重绘成本,要高于div元素。

重排何时发生

  • 添加或者删除可见的DOM元素。
  • 元素位置改变。
  • 元素尺寸改变。
  • 元素内容改变(例如:一个文本被另一个不同尺寸的图片替代)。
  • 页面渲染初始化(这个无法避免)。
  • 浏览器窗口尺寸改变。

最小化重绘和重排

  • DOM的多个读操作(或多个写操作),应该放在一起。不要两个读操作之间,加入一个写操作。

  • 如果某个样式是通过重排得到的,那么最好缓存结果。避免下一次用到的时候,浏览器又要重排。

  • 不要一条条地改变样式,而要通过改变class,或者csstext属性,一次性地改变样式。

// bad
var left = 10;
var top = 10;
el.style.left = left + "px";
el.style.top  = top  + "px";

// good 
el.className += " theclassname";

// good
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
  • 尽量使用离线DOM,而不是真实的网面DOM,来改变元素样式。比如,操作Document Fragment对象,完成后再把这个对象加入DOM。再比如,使用 cloneNode()方法,在克隆的节点上进行操作,然后再用克隆的节点替换原始节点。
<ul id='fruit'>
    <li> apple </li> 
    <li> orange </li>
</ul>

如果代码中要添加内容为peachwatermelon两个选项,你会怎么做?

let lis = document.getElementById('fruit');
let li=document.createElement('li');
li.innerHTML='apple';
lis.appendChild(li);

let li = document.createElement('li');
li.innerHTML = 'watermelon';
lis.appendChild(li);

很容易想到如上代码,但是很显然,重排了两次,怎么破?
前面我们说了,隐藏的元素不在渲染树中,太棒了,我们可以先把idfruitul元素隐藏(display=none),然后添加li元素,最后再显示,但是实际操作中可能会出现闪动,原因这也很容易理解。

这时,fragment元素就有了用武之地了。

let fragment = document.createDocumentFragment();

let li = document.createElement('li');
li.innerHTML = 'apple';
fragment.appendChild(li);

let li = document.createElement('li');
li.innerHTML = 'watermelon';
fragment.appendChild(li);

document.getElementById('fruit').appendChild(fragment);

文档片段是个轻量级的document对象,它的设计初衷就是为了完成这类任务——更新和移动节点。文档片段的一个便利的语法特性是当你附加一个片断到节点时,实际上被添加的是该片断的子节点,而不是片断本身。只触发了一次重排,而且只访问了一次实时的DOM

  • 先将元素设为display: none(需要1次重排和重绘),然后对这个节点进行100次操作,最后再恢复显示(需要1次重排和重绘)。这样一来,你就用两次重新渲染,取代了可能高达100次的重新渲染。

  • position属性为absolutefixed的元素,重排的开销会比较小,因为不用考虑它对其他元素的影响。

  • 只在必要的时候,才将元素的display属性为可见,因为不可见的元素不影响重排和重绘。另外,visibility : hidden的元素只对重绘有影响,不影响重排。

  • 使用虚拟DOM的脚本库,比如React等。

  • 使用window.requestAnimationFrame()window.requestIdleCallback()这两个方法调节重新渲染.

参考文档:
高性能JavaScript 重排与重绘
网页性能管理详解

相关文章

  • 网页性能管理:重绘和重排

    网页生成的过程 要理解网页性能为什么不好,就要了解网页是怎么生成的。 网页的生成过程,大致可以分成五步:1.HTM...

  • react 组件性能优化

    影响网页性能最大的因素是浏览器的重绘(reflow)和 重排 (repaint)。react 背后的 virtua...

  • 浏览器性能相关

    阮一峰写的一篇网页性能管理详解,文章中解释了浏览器重排、重绘的概念,比较清晰易懂。 总结点: 网页的生成过程主要是...

  • 简单谈谈开发过程中React组件的性能优化

    浏览器的重绘和重排版(reflows & repaints)(DOM操作都会引起)才是导致网页性能问题的关键。而R...

  • 浏览器页面的重绘和重排

    对于页面,我们经常有CSS对网页进行呈现样式效果,这就涉及到了页面的重绘和重排 重绘(repaints)与重排(r...

  • 浏览器的重绘和重排

    重绘和重排 重排是因为元素的几何属性改变,导致渲染树中的节点发生改变,从而影响到其它节点发生重绘。重排对性能影响极...

  • 前端收藏文章

    优化CSS重排重绘与浏览器性能

  • dom重排和重绘

    重绘不一定需要重排(比如颜色的改变),重排必然导致重绘(比如改变网页位置) DOM的变化影响了元素的几何属性,浏览...

  • 重绘和重排性能优化

    重绘和重排 1.1 DOM树和渲染树 浏览器下载完页面中的所有组件、HTML标记,javascript,css图片...

  • 浏览器重排(回流)重绘以及优化方案

    一、什么是重排和重绘 要说清重排(reflow)和重绘(repaint),首先要理解排列和绘制,浏览器渲染页面时,...

网友评论

    本文标题:网页性能管理:重绘和重排

    本文链接:https://www.haomeiwen.com/subject/rzhzrxtx.html