JavaScript 性能优化

#JavaScript性能优化实战#

一、代码层面的优化

  1. 减少不必要的操作

    • 避免重复计算:在循环中将不变的值缓存到变量中。

    javascript

    复制

    下载

    // 优化前
    for (let i = 0; i < arr.length; i++) { ... }
    
    // 优化后
    const len = arr.length;
    for (let i = 0; i < len; i++) { ... }
    • 避免全局变量:局部变量访问速度更快。

    javascript

    复制

    下载

    // 优化前:频繁访问全局变量
    function calc() { console.log(window.value); }
    
    // 优化后:缓存为局部变量
    function calc() {
      const value = window.value;
      console.log(value);
    }
  2. 高效使用循环

    • 优先使用 for 或 while 循环而非 forEach(大数据量时更明显)。

    • 倒序循环(i--)可能略微提升性能(减少条件判断次数)。

  3. 事件委托

    • 利用事件冒泡,减少事件监听器数量:

    javascript

    复制

    下载

    // 优化前:为每个按钮绑定事件
    document.querySelectorAll('button').forEach(btn => {
      btn.addEventListener('click', handleClick);
    });
    
    // 优化后:委托到父元素
    document.getElementById('parent').addEventListener('click', (e) => {
      if (e.target.tagName === 'BUTTON') handleClick(e);
    });

二、数据存取优化

  1. 作用域链与原型链

    • 减少深层作用域链查找,优先使用局部变量。

    • 避免过深的原型链访问(如 obj.a.b.c.d),可通过中间变量缓存。

  2. 数据结构选择

    • 高频查询场景使用 Map/Set 替代 Object(哈希表效率更高)。

    • 使用 TypedArray 处理二进制数据(如 WebGL、Canvas)。


三、DOM 操作优化

  1. 减少 DOM 访问次数

    • 批量修改 DOM:使用 documentFragment 或离线 DOM 操作。

    javascript

    复制

    下载

    const fragment = document.createDocumentFragment();
    for (let i = 0; i < 1000; i++) {
      const div = document.createElement('div');
      fragment.appendChild(div);
    }
    document.body.appendChild(fragment);
    • 读写分离:避免交替读写布局属性(如 offsetWidth),触发强制重排。

  2. 减少重排(Reflow)与重绘(Repaint)

    • 使用 transform 和 opacity 实现动画(触发 GPU 加速)。

    • 集中样式修改:通过修改 class 而非逐行修改 style

    • 使用 requestAnimationFrame 优化动画:

    javascript

    复制

    下载

    function animate() {
      element.style.left = `${pos}px`;
      pos++;
      requestAnimationFrame(animate);
    }

四、内存管理

  1. 避免内存泄漏

    • 及时解绑无用的事件监听器、定时器。

    • 避免意外的闭包引用:

    javascript

    复制

    下载

    // 错误示例:闭包引用大对象
    function init() {
      const largeData = new Array(1e6).fill('data');
      document.getElementById('btn').addEventListener('click', () => {
        console.log(largeData); // largeData 无法释放!
      });
    }
    • 清除无效的 DOM 引用(如已移除元素的缓存)。

  2. 使用弱引用

    • 通过 WeakMap/WeakSet 管理临时关联数据,避免阻止垃圾回收。


五、网络与加载优化

  1. 减少脚本体积

    • 代码压缩(Terser)、Tree Shaking 删除无用代码。

    • 按需加载:使用动态 import() 或代码分割(Webpack/Rollup)。

    javascript

    复制

    下载

    // 动态导入
    button.addEventListener('click', async () => {
      const module = await import('./heavy-module.js');
      module.run();
    });
  2. 合理加载脚本

    • 使用 defer 或 async 属性避免阻塞渲染。

    html

    复制

    下载

    运行

    <script src="app.js" defer></script> <!-- 延迟执行,不阻塞 DOM 解析 -->
    <script src="analytics.js" async></script> <!-- 异步加载,执行时机不确定 -->
  3. 利用浏览器缓存

    • 设置 Cache-Control/ETag 响应头缓存静态资源。

    • 使用 Service Worker 实现离线缓存(PWA)。


六、异步与并行

  1. Web Workers

    • 将 CPU 密集型任务(如数据处理)转移到 Worker 线程:

    javascript

    复制

    下载

    // 主线程
    const worker = new Worker('task.js');
    worker.postMessage(data);
    worker.onmessage = (e) => { /* 处理结果 */ };
    
    // task.js
    self.onmessage = (e) => {
      const result = heavyCalculation(e.data);
      self.postMessage(result);
    };
  2. 合理使用微任务与宏任务

    • 优先使用 Promise/queueMicrotask 而非 setTimeout(fn, 0)


七、工具与监控

  1. 性能分析工具

    • Chrome DevTools 的 Performance 面板分析运行时性能。

    • Memory 面板检测内存泄漏。

    • Lighthouse 生成性能优化报告。

  2. 性能监控

    • 使用 PerformanceObserver API 监控关键指标(如首次输入延迟、长任务)。

    javascript

    复制

    下载

    const observer = new PerformanceObserver((list) => {
      for (const entry of list.getEntries()) {
        console.log('长任务:', entry);
      }
    });
    observer.observe({ entryTypes: ['longtask'] });

总结

性能优化需结合具体场景权衡,核心思路是:

  1. 减少计算量:优化算法复杂度(如 O(n²) → O(n))。

  2. 减少 I/O 操作:包括 DOM 操作、网络请求。

  3. 并行化:利用 Web Workers、异步任务。

  4. 内存友好:及时释放无用资源,避免泄漏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zqmattack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值