基本概念

DOM树(DOM tree):浏览器解析HTML文本创建的树结构

CSSOM(CSS Object Model):将样式表中的规则映射到页面对应的元素上

渲染树(render tree):CSSOM和DOM树合并成渲染树,只包含渲染网页所需的节点

重排(relayout):在Firefox中被称为reflow(回流),部分或整个渲染树需要重新分析并且节点尺寸需要重新计算

重绘(repaint/redraw):节点的几何属性或样式发生改变,屏幕进行内容的更新,称为重绘

触发重排与重绘的情况

重排

  • 页面第一次渲染 在页面发生首次渲染的时候,所有组件都要进行首次布局,这是开销最大的一次重排

  • 浏览器窗口尺寸改变

  • 元素位置和尺寸发生改变的时候

  • 新增和删除可见元素

  • 内容发生改变(文字数量或图片大小等等)

  • 元素字体大小变化

  • 激活CSS伪类

  • 设置style属性

  • 查询某些属性或调用某些方法,比如说:

    offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

重绘

  • vidibilityoutline、背景色等属性的改变

重绘不一定导致重排,重排一定导致重绘

避免或减少重排带来的开销

分离读写操作

div.style.top = "10px";
div.style.bottom = "10px";
div.style.right = "10px";
div.style.left = "10px";
console.log(div.offsetWidth);
console.log(div.offseHeight);
console.log(div.offsetRight);
console.log(div.offsetLeft);

原来的操作会导致四次重排和四次重绘,变换顺序之后只会触发一次重排 在第一个console的时候,浏览器把之前上面四个写操作的渲染队列都给清空了。因为渲染队列本来就是空的,所以剩下的console并没有触发重排,仅仅拿值而已。

样式集中改变

通过classcssText进行集中改变样式

缓存布局信息

// bad 强制刷新 触发两次重排
div.style.left = div.offsetLeft + 1 + 'px';
div.style.top = div.offsetTop + 1 + 'px';

// good 缓存布局信息 相当于读写分离
var curLeft = div.offsetLeft;
var curTop = div.offsetTop;
div.style.left = curLeft + 1 + 'px';
div.style.top = curTop + 1 + 'px';

DOM离线

  • 一旦我们给元素设置display:none时,元素不会存在于渲染树中,相当于将其从页面“拿掉”,我们之后的操作将不会触发重排和重绘,这叫做DOM的离线化。

  • 通过使用DocumentFragment创建一个dom碎片,在它上面批量操作dom,操作完成之后,再添加到文档中,这样只会触发一次重排。

    <ul id="list"></ul>
    const list = document.querySelector('#list');
    const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];
    
    const fragment = document.createDocumentFragment();
    
    fruits.forEach(fruit => {
      const li = document.createElement('li');
      li.innerHTML = fruit;
      fragment.appendChild(li);
    });
    
    list.appendChild(fragment);

将position属性设置为absolute或fixed

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

优化动画

  • 把动画效果应用到position属性为absolutefixed的元素上,这样对其他元素影响较小
  • 启用GPU加速

原文链接

https://juejin.im/entry/582f16fca22b9d006b7afd89

https://imweb.io/topic/5c2206a7611a25cc7bf1d848


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

只出现一次的数字 上一篇
leaflet自定义popup弹框样式 下一篇