javascript的性能如何优化_哪些技巧能提升执行速度

避免在循环中重复计算数组长度,应缓存 arr.length;去重优先用 Set;防抖节流需按场景选用,避免滥用;优先优化 DOM 访问和内存泄漏,再考虑 JS 执行性能。

避免在循环中重复计算数组长度

常见错误是把 arr.length 直接写在 for 循环条件里,尤其当数组很大或 length 被代理/访问器劫持时,每次迭代都触发 getter,开销明显。

  • 用变量缓存: const len = arr.length; for (let i = 0; i
  • 对普通数组,现代引擎(V8、SpiderMonkey)多数能自动优化,但不保证;对 HTMLCollection 或带 getter 的类数组对象,必须手动缓存
  • 更安全的替代是使用 for...of,它不依赖 length,且语义清晰

减少 DOM 操作频次与重排重绘

每次读写 offsetTopclientWidth 或修改 style 属性,都可能触发强制同步布局(forced synchronous layout),性能杀手。

  • 批量读取:先集中读所有需要的尺寸,再集中写样式
  • 批量写入:用 element.classList.add() 替代多次 element.style.xxx = yyy
  • documentFragment 批量插入节点,避免多次挂载触发重排
  • 动画优先用 transformopacity,它们走合成层,不触发重排
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const el = document.createElement('div');
  el.textContent = `Item ${i}`;
  fragment.appendChild(el);
}
container.appendChild(fragment); // 仅一次真实 DOM 插入

善用 Map/Set 替代对象/数组做查找

当需要高频判断“是否存在某 key 或某值”时,Object.prototype.hasOwnProperty()array.includes() 是 O(n);而 Map.has()Set.has() 是平均 O(1)。

  • 键为字符串且数量大时,Map 比普通对象快,且支持任意类型键
  • 去重场景无脑用 new Set(arr),比 filter((v, i) => arr.indexOf(v) === i) 快一个数量级
  • 注意:如果只是少量静态配置(如 5 个状态映射),对象字面量反而更轻量,别过度设计

函数防抖与节流不是万能解药

很多人一遇到高频回调(如 resizeinput)就加 debounce,但容易掩盖真正问题:比如监听了整个窗口 resize 却只为了更新一个元素宽高。

  • 优先缩小监听范围:用 ResizeObserver 观察具体目标元素,而不是全局 resize
  • debounce 延迟执行,适合搜索建议;throttle 限制频率,适合滚动视差——选错策略会让体验变卡或响应滞后
  • 简单逻辑(如开关 class)可直接内联处理,加一层防抖函数反而增加闭包和定时器开销

最常被忽略的是:性能瓶颈往往不在 JS 执行本身,而在 DOM 访问模式、内存泄漏(如未清理事件监听器)、或过早优化。先用 Performance 面板录一段真实操作,看火焰图里哪条堆栈占 CPU 最久,再动手改。