侧边栏壁纸
  • 累计撰写 47 篇文章
  • 累计创建 2 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

性能优化:重绘和重排

重绘和重排是什么?

重排:当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来。
重绘:当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式。

原因

我们只要关心渲染引擎(Rendering engine)和 JS 引擎(JavaScript Interpreter)也可称为 JS 解析器。JS 引擎和渲染引擎是独立实现的,两者通过桥接接口通信。而 DOM 由渲染引擎绘制,所以,当 JS 改变 DOM 结构时,必须通过 Bridge 通知给渲染引擎,然后进行重排或者重绘。这个通信是有开销的。

优化点

重排的开销要远大于重绘

  1. 尽可能减少 DOM 操作
  2. 尽可能减少重排
例子

例 1:在 container 元素里面添加 10000 个节点

不好的行为:

  1. JS 多次读取 DOM 元素
for(var count=0;count<10000;count++){ 
  document.getElementById('container').innerHTML+='<span>hello</span>';
}
  1. JS 多次更改 DOM 元素
let container = document.getElementById('container');
for(let count=0;count<10000;count++){ 
  container.innerHTML += '<span>hello</span>';
}

好的行为:用 DocumentFragment 容器做内容拼接

let container = document.getElementById('container');
// 创建一个DOM Fragment对象作为容器
let content = document.createDocumentFragment();
for(let count=0;count<10000;count++){
  // 通过DOM API创建span
  let spanElt = document.createElement("span");
  spanElt.innerHTML = 'hello';
  // 像操作真实DOM一样操作DOM Fragment对象
  content.appendChild(spanElt);
}
// 最后更改DOM
container.appendChild(content)

例 2:更改元素样式

不好的行为:逐条更改样式

const container = document.getElementById('container')
container.style.width = '100px';
container.style.height = '200px';
container.style.color = 'red';

好的行为:

  1. 只改动一次样式
.basic_style {
   width: 100px;
   height: 200px;
   color: red;
}
//app.js
const container = document.getElementById('container');
container.classList.add('basic_style');
  1. 当 DOM 离线时(display: none),无论怎么操作,浏览器都不会绘制它,也就不会引发重排或者重绘。
let container = document.getElementById('container');
container.style.display = 'none';
container.style.width = '100px';
container.style.height = '200px';
container.style.color = 'red';

container.style.display = 'block'
注意

需要注意的是,这些属性要慎用,因为这些属性都需要实时计算得到,所以浏览器为了取得正确的值,会进行重排!

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

0

评论区