重绘(repaint)和回流/重排(reflow)介绍,以及如何进行优化

首先了解浏览器的渲染过程

1、浏览器渲染过程

重绘(repaint)和回流/重排(reflow)介绍,以及如何进行优化_第1张图片
(截自chenjigeng作者的图)

  • 浏览器采用流式布局;
  • 解析HTML—DOM树,解析CSS—CSSOM树,DOM + CSSOM => 渲染树;
  • 根据生成的渲染树,进行回流(layout),得到节点的位置、大小;
  • 根据之前得到的信息,进行重绘(painting),得到节点的绝对像素;
  • 将像素发送给GPU,节点绘制到页面上;

2、回流

发生机制:

  • 页面初始渲染;
  • 添加/删除元素;
  • 位置、尺寸(包括边距大小、高度、宽度)、内容(文本、图片替换)变化;
  • 浏览器窗口大小变化;
  • display:none,脱离了文档流;
回流一定会触发重绘,而重绘不一定会回流

3、重绘

发生机制:

  • 颜色
  • visibility: hidden,元素还是占了位置的

4、优化机制

  • 避免频繁使用0ffsetTop/Left/Width/Height、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、width/height(大多浏览器是通过队列化修改、执行重排过程,而这些属性需要返回最近的值,浏览器就得清空队列,触发回流/重排);
const width = box.offsetWidth;
function initP() {
    for (let i = 0; i < paragraphs.length; i++) {
    	// 每次循环都会读取offsetWidth,强制浏览器刷新队列,放到循环外避免这种情况
    	// paragraphs[i].style.width = box.offsetWidth + 'px'; 
        paragraphs[i].style.width = width + 'px';
    }
}
  • 将动画效果应用到positions: absolute/fixed元素上,脱离文档流,避免父元素以及有影响的元素频繁的回流;
  • JS方面,避免频繁操作样式、DOM;
const el = document.getElementById('test');
el.style.cssText += 'border-left: 1px; border-right: 2px; padding: 5px;';
// or
el.className += ' active';
  • css3硬件加速(GPU加速),可以让transform、opacity、filters这些动画不会引起回流重绘;

5、扩展知识

vue中v-if与v-show的区别:

v-if:条件渲染,条件为false时是不做渲染的,切换过程中内部事件监听和子组件会适当的销毁和重建;切换消耗较高;
v-show:无论是true还是false,元素都会渲染,使用display来控制显示隐藏;初始渲染消耗较高,适合频繁切换场景;

PS:学习的重绘和回流介绍问题回答作者

你可能感兴趣的:(css)