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

94 阅读3分钟

性能优化:

减少重绘和重排:

CSS解决

  1. 使用 CSS 隐藏元素:如果需要隐藏元素,最好使用 CSS 的 display: nonevisibility: hidden,而不是直接修改元素的 style 属性。这样可以避免重绘和重排,因为浏览器会在布局流程中将隐藏的元素排除在外。
.hidden-element {
  display: none;
}
  1. 避免对样式进行多次修改,可以将多个样式属性的修改合并到一起,或者使用 CSS 类来一次性修改多个样式属性
/* 定义一个 CSS 类 */
.example-class {
  background-color: red;
  color: white;
  font-size: 16px;
}
const element = document.getElementById('example-element');
// 添加类
element.classList.add('example-class');
// 移除类
element.classList.remove('example-class');
// 切换类
element.classList.toggle('example-class');

使用 CSS3 的变换(transform)和动画(animation)属性,它们通常能更高效地进行动画渲染。

JavaScript解决

  1. 缓存 DOM 查询结果:在使用 JavaScript 操作 DOM 时,尽量避免频繁查询相同的元素。可以将查询结果存储在变量中,以便后续重复使用。这样可以减少对 DOM 的重复访问,提高性能。
const element = document.getElementById('myElement');
// 避免在后续的操作中重复查询
element.classList.add('active');
element.style.color = 'red';
  1. 使用 document.createDocumentFragment():当需要动态插入大量元素时,使用 document.createDocumentFragment() 可以避免频繁的 DOM 操作,从而提高性能。
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const element = document.createElement('div');
  element.textContent = 'Element ' + i;
  fragment.appendChild(element);
}
document.querySelector('#container').appendChild(fragment);
  1. 批量修改样式:如果需要修改多个元素的样式,最好将它们的样式更改放在一个样式类中,并一次性添加或删除该类。这样可以减少对每个元素的重绘和重排。
const elements = document.querySelectorAll('.myElement');
// 先添加样式类,再一次性应用
elements.forEach(element => element.classList.add('highlight'));

节流和防抖:

  • 节流是一种限制函数执行频率的技术,可以在特定时间间隔内执行函数。它适用于需要控制某些高频事件(如滚动、拖拽、鼠标点击等)的触发频率。
function throttle(fn, delay) {
  let timer = null;
  return function() {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, arguments);
        timer = null;
      }, delay);
    }
  };
}

// 使用节流函数
const throttledFn = throttle(() => {
  console.log('Throttled function');
}, 1000);
  • 防抖是一种延迟执行函数的技术,它会等待一段时间后再执行函数。它适用于在特定时间间隔内只执行一次函数的场景,例如搜索框输入时的自动补全功能。
function debounce(fn, delay) {
  let timer = null;

  return function() {
    clearTimeout(timer);

    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
}

// 使用防抖函数
const debouncedFn = debounce(() => {
  console.log('Debounced function');
}, 1000);

添加防抖,节流函数根据情况而定,一般用于高频场合,能有效调高系统流畅

优化循环和迭代:

  • 当使用循环或迭代对集合进行操作时,尽量使用优化的遍历方式,forEach>for>while,多使用break,continue
  • 注意在循环中避免频繁地进行DOM操作,可以在循环外先进行计算和处理,最后一次性进行 DOM 操作。
  • 每次循环内避免重复计算,可以考虑将它们提取到循环外部或者使用一个变量来缓存结果,避免在每次循环迭代中重复计算。

使用性能分析工具:

  • 浏览器开发者工具(如 Chrome DevTools)提供了强大的性能分析功能,可以帮助定位性能瓶颈和优化点。通过查看页面加载时间线、CPU 和内存使用情况等指标,可以找到需要优化的代码段。
  • 使用WebPageTest 等工具对网站进行性能测试和评估,并提供详细的性能优化建议。

使用事件委托:

<ul id="myList">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

<script>
document.getElementById("myList").addEventListener("click", function(event) {
  if (event.target.nodeName === "LI") {
    // 只有点击列表项时才执行处理逻辑
    console.log("Clicked on", event.target.textContent);
  }
});
</script>
  • 通过将事件处理程序绑定到共同的父元素上,并利用事件冒泡机制,在父元素上捕获事件,减少了绑定事件处理程序的数量,提高了性能。
  • 特别是在处理大量列表或动态内容时,事件委托可以有效减少事件处理程序的数量。

调试技巧

console.log()

通过在js代码中加入console.log(1),来判断代码出错的位置

往往最简单的东西,越好用

debugger

console.log()用法类似,当执行到该语句时,代码将暂停并进入调试模式。

浏览器开发者工具

以下用Chrome 举例

image-20230728141659994

一般用看控制台打印结果网络报错提示