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

109 阅读6分钟

减少重绘和重排

​ ​ ​ ​ ​ ​ ​ ​ 减少重绘和重排需要尽量减少对DOM的频繁操作,使用合适的CSS属性和技术来优化渲染过程,并且避免强制同步布局,使得浏览器可以最优化地处理渲染任务。

  1. 批量DOM操作:在进行多个DOM操作时,尽量将它们合并成一个操作,从而减少多次重排和重绘。可以使用DocumentFragment或虚拟DOM来缓存和合并DOM更新。
  2. 使用CSS3过渡和动画:利用CSS3过渡和动画,这些属性通常会优化为GPU加速,减少对布局的影响,提高性能。
  3. 使用transform和opacity:对于动画效果,尽量使用transform和opacity属性,因为它们可以在不影响布局的情况下进行动画,减少重排。
  4. 离线操作:在需要多次更新DOM时,将元素从DOM树中删除,进行离线操作,然后再将元素插入回DOM树中,这样可以最小化重排和重绘的次数。
  5. 使用虚拟化列表:对于大型列表,使用虚拟化技术(如React中的Virtualized List)只渲染可见的部分,而不是所有的列表项,从而减少渲染的DOM数量。
  6. 避免频繁的样式读写操作:频繁地读取和写入样式会导致多次重排和重绘。最好通过添加/移除CSS类来批量修改样式,或者使用CSS样式字符串一次性更新多个样式。
  7. 使用display:none替代visibility:hidden:visibility:hidden会触发重绘,而display:none则会触发重排和重绘。当需要隐藏元素时,最好使用display:none来避免重排。
  8. 优化CSS选择器:复杂的CSS选择器可能会导致性能下降。尽量使用简单的选择器,并且避免使用通用选择器。
  9. 使用position:fixed或position:absolute:对于需要动画效果的元素,使用position:fixed或position:absolute来将其脱离文档流,避免影响其他元素的布局。
  10. 缓存计算结果:在某些计算量较大的情况下,可以缓存计算结果,避免多次重复计算,提高性能。

使用节流和防抖技术

节流是什么

节流是一种限制事件处理函数在一定时间间隔内只能执行一次的技术。当事件触发时,如果在指定的时间间隔内已经执行过处理函数,则不会再次触发执行,直到过了指定的时间间隔后才能再次执行。节流适用于一些频繁触发的事件,如窗口resize或滚动事件。

节流的使用

function throttle(func, delay) {
  let timer = null;
  return function (...args) {
    if (timer) return;
    func.apply(this, args);
    timer = setTimeout(() => {
      timer = null;
    }, delay);
  };
}
const handleScroll = () => {
  console.log("Scroll event is throttled.");
};
const throttledScroll = throttle(handleScroll, 200);
window.addEventListener('scroll', throttledScroll);

​ ​ ​ ​ ​ ​ ​ ​ 在上面的例子中,我们定义了一个throttle函数,该函数接受两个参数:func为实际的事件处理函数,delay为事件触发的时间间隔限制。当事件被触发时,throttle函数会判断是否已经设置了定时器,如果有则直接返回,否则执行实际的事件处理函数并设置一个定时器,在delay毫秒后清除定时器。这样就保证了事件处理函数在指定时间间隔内只能执行一次。

防抖是什么

防抖是一种延迟事件处理函数的执行,只有在事件触发后等待一定的时间间隔,如果在这个时间间隔内没有再次触发事件,那么事件处理函数才会被执行。如果在等待的时间间隔内事件再次触发,那么计时重新开始。防抖适用于一些需要等待一段时间后执行的事件,如搜索框输入事件。

防抖的使用

function debounce(func, delay) {
  let timer = null;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}
const handleInput = () => {
  console.log("Input event is debounced.");
};
const debouncedInput = debounce(handleInput, 500);
inputElement.addEventListener('input', debouncedInput);

​ ​ ​ ​ ​ ​ ​ ​ 在上面的例子中,我们定义了一个debounce函数,该函数接受两个参数:func为实际的事件处理函数,delay为事件触发的延迟时间。当事件被触发时,debounce函数会先清除之前设置的定时器,然后重新设置一个定时器,在delay毫秒后执行实际的事件处理函数。如果在delay毫秒内事件再次触发,之前设置的定时器会被清除,重新开始计时。

两者的不同之处

​ ​ ​ ​ ​ ​ ​ ​节流和防抖技术的效果和时间间隔的设置都应根据具体的场景来调整。节流可以用于频繁触发的事件,以减少处理函数的执行次数;而防抖适用于需要等待一段时间后才执行的事件,避免不必要的执行。

使用性能分析工具

​ ​ ​ ​ ​ ​ ​ ​通过使用性能分析工具,开发者可以深入分析JavaScript代码的执行情况,包括函数的执行时间、资源的消耗等。性能分析工具可以帮助开发者找出耗时较长的函数和操作,以及消耗大量资源的地方,从而帮助定位性能瓶颈。从而可以有针对性地优化代码,例如采用更高效的算法、减少DOM操作次数、缓存重复计算结果、使用节流和防抖技术等。优化后的代码能够减少不必要的计算和操作,提高页面的响应速度和加载性能,从而改善用户体验。

Edge浏览器分析

  1. 开Edge浏览器,并打开你要进行性能分析的网页。
  2. 按下F12键(或者右键点击页面,选择“检查”选项)打开开发者工具。
  3. 在开发者工具中,点击顶部导航栏中的"Performance"选项卡。
  4. 点击“开始记录”按钮(一个圆形红色按钮)来开始记录性能数据。你可以选择设置一个合适的时间范围来记录性能,也可以直接点击“刷新”按钮重新加载页面并记录性能。
  5. 交互操作:在记录性能的过程中,进行一些和性能相关的交互操作,例如滚动页面、点击按钮、执行一些JavaScript代码等。
  6. 停止记录:完成交互操作后,点击“停止记录”按钮(同样是一个圆形红色按钮)停止记录性能数据。
  7. 查看性能数据:在停止记录后,性能面板会显示一个时间轴和各种性能相关的信息,包括CPU使用情况、内存使用情况、事件时间线等。你可以查看性能概览,并点击时间轴上的各个事件来查看详细的性能数据。
  8. 分析性能:通过查看性能数据,你可以找出耗时较长的JavaScript函数或事件,定位性能瓶颈,并优化代码以提高性能。 tmp.png