javascript 性能优化实例一则

减少重绘和回流

在JavaScript中,频繁操作DOM会导致浏览器重绘和回流,影响性能。可以通过合并DOM操作或使用文档片段(DocumentFragment)来减少重绘和回流次数。

复制代码
// 低效方式:多次操作DOM
for (let i = 0; i < 100; i++) {
  document.body.appendChild(document.createElement('div'));
}

// 高效方式:使用文档片段
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  fragment.appendChild(document.createElement('div'));
}
document.body.appendChild(fragment);

使用事件委托

事件委托利用事件冒泡机制,将事件处理程序绑定到父元素而非每个子元素,减少内存消耗和事件绑定时间。

复制代码
// 低效方式:为每个子元素绑定事件
document.querySelectorAll('li').forEach(li => {
  li.addEventListener('click', () => {
    console.log(li.textContent);
  });
});

// 高效方式:事件委托
document.querySelector('ul').addEventListener('click', (e) => {
  if (e.target.tagName === 'LI') {
    console.log(e.target.textContent);
  }
});

避免频繁操作样式

直接修改元素的style属性会导致多次回流。可以通过添加或移除CSS类名来批量修改样式。

复制代码
// 低效方式:直接修改style
element.style.width = '100px';
element.style.height = '200px';
element.style.backgroundColor = 'red';

// 高效方式:使用CSS类名
element.classList.add('active');

使用节流和防抖

对于频繁触发的事件(如scroll、resize),使用节流(throttle)或防抖(debounce)技术减少事件处理函数的执行频率。

复制代码
// 防抖实现
function debounce(func, delay) {
  let timer;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(() => func.apply(this, arguments), delay);
  };
}

window.addEventListener('resize', debounce(() => {
  console.log('Resize event handled');
}, 200));

// 节流实现
function throttle(func, limit) {
  let inThrottle;
  return function() {
    if (!inThrottle) {
      func.apply(this, arguments);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}

window.addEventListener('scroll', throttle(() => {
  console.log('Scroll event handled');
}, 100));

优化循环性能

在循环中避免重复计算或访问DOM,可以通过缓存变量或减少循环次数提升性能。

复制代码
// 低效方式:重复访问DOM
for (let i = 0; i < document.querySelectorAll('div').length; i++) {
  console.log(document.querySelectorAll('div')[i].textContent);
}

// 高效方式:缓存DOM查询结果
const divs = document.querySelectorAll('div');
const length = divs.length;
for (let i = 0; i < length; i++) {
  console.log(divs[i].textContent);
}

使用Web Workers处理耗时任务

将耗时任务(如大数据处理)放到Web Worker中执行,避免阻塞主线程。

复制代码
// 主线程代码
const worker = new Worker('worker.js');
worker.postMessage({ data: largeArray });
worker.onmessage = (e) => {
  console.log('Result:', e.data);
};

// worker.js
self.onmessage = (e) => {
  const result = e.data.data.map(processData);
  self.postMessage(result);
};

合理使用缓存

对于重复计算或请求的数据,使用缓存机制避免重复处理。

复制代码
const cache = {};
function expensiveOperation(key) {
  if (cache[key]) {
    return cache[key];
  }
  const result = /* 复杂计算 */;
  cache[key] = result;
  return result;
}
相关推荐
伞伞悦读10 小时前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
卡布鲁10 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
C语言小火车10 小时前
C/C++ 为什么需要编译器?
开发语言·c++
李少兄10 小时前
JavaScript 隐式全局变量解析
javascript
霍霍的袁11 小时前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超12 小时前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int12 小时前
深入理解C++系列(20)——C++11(下)
开发语言·c++
沙蒿同学12 小时前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端
CoderYanger13 小时前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
paopaokaka_luck13 小时前
智慧社区综合服务小程序(人脸识别、AI问答、Echarts图形化分析)
前端·javascript·spring boot·spring·数据分析·echarts