性能优化与调试技巧 | 青训营

43 阅读3分钟

性能优化——减少重绘重排

网页生成过程如下: image.png 第四步:重新生成布局(重排)->修改布局
第五步:重新绘制(重绘)->修改颜色等样式,布局不变

减少重排和重绘的方法

  1. 使用 CSS3 动画和过渡效果:CSS3 动画和过渡效果可以利用 GPU 加速,减少对页面布局的影响,从而减少重绘和重排的次数。
<!-- HTML -->
<div class="box"></div>
/* CSS */
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  transition: width 0.3s ease-in-out;
}

.box:hover {
  width: 200px;
}
  1. 批量修改样式:对于需要修改多个样式属性的操作,可以将它们合并为一次操作,而不是多次单独操作。这样可以减少重绘和重排的次数。
  2. 使用文档片段(Document Fragment):在操作 DOM 时,可以使用文档片段来创建和修改 DOM 结构,然后将整个文档片段一次性添加到页面中。这样可以减少对 DOM 的多次修改,从而减少重绘和重排的次数。
  3. 缓存布局信息:在需要多次读取元素的布局信息(如宽度、高度、位置等)时,可以将这些信息缓存起来,避免多次触发重排。
// JavaScript
const element = document.getElementById('myElement');
const elementWidth = element.offsetWidth; // 缓存元素宽度
const elementHeight = element.offsetHeight; // 缓存元素高度

// 对 elementWidth 和 elementHeight 进行操作,不会引起重排和重绘

通过在需要多次访问元素宽度和高度的地方缓存这些信息,避免了多次触发重排

  1. 使用 transform 和 opacity 进行动画:当需要对元素进行动画效果时,使用 transform 属性和 opacity 属性可以利用 GPU 加速,减少对布局的影响。
// JavaScript
function animateElement() {
  const element = document.getElementById('myElement');
  let position = 0;

  function animate() {
    position += 1;
    element.style.transform = `translateX(${position}px)`;

    if (position < 200) {
      requestAnimationFrame(animate);
    }
  }

  animate();
}

requestAnimationFrame会在下一次浏览器重绘之前执行回调函数animate,从而优化动画的性能。通过在每一帧中更新元素的transform属性,我们可以实现平滑的位移动画,避免了不必要的重排和重绘。

  1. 避免频繁访问布局信息:避免在 JavaScript 中频繁访问元素的布局信息,因为每次访问都会触发重排。最好在一次操作中获取所需的布局信息,并将其缓存起来供后续使用。
  2. 可以使用 requestAnimationFrame 方法来优化动画的性能。它可以在下一次浏览器重绘之前执行操作,以避免不必要的重绘和重排。

调试技巧——Chrome DevTools

Element

  1. 输入字符串可以动态给元素添加类名
  2. 点击具体的样式可以实时预览
  3. 强制激活伪类
  1. 选中具有伪类的元素,点击:hov
  2. Dom树右键菜单 force state

Console

  1. console.log 灰色
  2. console.warn 黄色
  3. console.error 红色
  4. console.debug 蓝色
  5. console.info 白色
  6. console.table 具象化展示json
  7. console.dir 文件树
  8. 占位符 %s 字符串, %o 对象 ,%c 样式 ,%d 数字

Source

image.png image.png

Performance

下面是一些常用的Performance API的方法和属性:

  1. performance.timing:包含了与页面加载和各个阶段相关的时间戳信息,如页面开始加载的时间、DOM准备完成的时间、脚本加载完成的时间等。可以使用这些时间戳来计算页面加载时间和各个阶段的耗时。
  2. performance.now():返回一个高精度的时间戳,通常用于测量和计算代码执行的时间。可以使用它来进行性能分析和优化,例如测量函数的执行时间。
  3. performance.mark()performance.measure():用于创建和测量自定义的性能标记。可以使用performance.mark()在代码中插入标记点,然后使用performance.measure()来测量两个标记点之间的时间差,从而获取代码片段的执行时间。
  4. performance.getEntries():返回一个包含所有已完成的性能条目的数组。每个性能条目都包含了与特定资源或行为相关的性能数据,如请求时间、响应大小、传输时间等。可以使用它来进一步分析和优化资源加载和网络请求等方面的性能。
  5. performance.memory:包含了与内存使用相关的信息,如已分配的内存量、使用的内存量等。可以使用它来监控和分析网页的内存使用情况。

通过使用Performance API提供的方法和属性,可以对网页的性能进行监控、分析和优化。这样可以找到性能瓶颈,并采取相应的措施来提高网页的加载速度和响应性能,提升用户体验。

Network

image.png

image.png