← 返回目录

第 4 卷

第 4 / 7 卷日期:

10. JavaScript代码性能优化操作

下:

  1. 减少主线程阻塞,避免长任务

◦ 使用 Web Worker:将耗时计算(如大数据处理、复杂算法)放到 Web Worker 中执行,Web

Worker 运行在后台线程,不阻塞主线程(UI 渲染和交互)

◦ 拆分长任务:将超过 50ms 的长任务拆分为多个小任务,通过 requestIdleCallback 或

setTimeout 分批执行,避免主线程卡顿

  1. 优化数据操作,降低计算复杂度

◦ 数据查询优化:使用 Map/Set 替代 Array 进行高频查询(Map 的查找时间复杂度为 O(1),

Array 的 indexOf / find 为 O(n))

Code block

1// 低效:Array 查找 2const arr = [{ id: 1, name: 'a' }, { id: 2, name: 'b' }];

3const target = arr.find(item => item.id === 2); // O(n)

4 5// 高效:Map 查找

6const map = new Map([[1, { name: 'a' }], [2, { name: 'b' }]]);

7const target = map.get(2); // O(1)

◦ 避免不必要的循环嵌套:循环嵌套的时间复杂度通常为 O(n²) 甚至更高,尽量优化为单层循环

◦ 缓存计算结果:对重复计算的结果进行缓存(如斐波那契数列的递归优化、组件渲染中的计算

属性缓存)

  1. 优化DOM操作(前文补充,此处核心强调)

◦ 减少直接 DOM 操作,优先使用虚拟 DOM 或框架提供的 API

◦ 使用事件委托(事件冒泡机制),减少事件绑定数量

Code block

1//事件委托:仅给父元素绑定1个事件,处理所有子元素的点击事件
2document.getElementById('parent').addEventListener('click', (e) => {
3if (e.target.tagName === 'LI') {
4console.log(e.target.textContent);
5}
6});

◦ 避免频繁创建匿名函数:匿名函数无法被缓存,频繁创建会增加内存开销(如在 render 方

◦ 函数柯里化/防抖节流:减少不必要的函数执行(后文详细说明)

◦ 避免递归深度过深:递归深度过深会导致调用栈溢出,可改为迭代实现

  1. 优化资源加载,减少JS执行时间

◦ 使用 defer / async 加载非关键 JS 脚本:

▪ async:异步加载脚本,加载完成后立即执行(不保证执行顺序)

▪ defer:异步加载脚本,页面解析完成后按顺序执行(推荐用于需要保证执行顺序的非关

键脚本)

Code block

1<script src="app.js" defer></script> 2<script src="vendor.js" async></script>

◦ 压缩JS代码:使用 Terser、UglifyJS 等工具压缩 JS,移除注释、空格、未使用代码,减小文件

体积,提升加载和执行速度

  1. 其他优化点

◦ 避免频繁操作数组的 shift / unshift(会移动数组所有元素,时间复杂度 O(n)),优先

使用 push / pop(时间复杂度 O(1))

◦ 使用 const / let 替代 var,提升代码可读性的同时,避免变量提升带来的不必要开销

◦ 减少不必要的属性访问:优先缓存对象属性,避免频繁深层访问(如 obj.a.b.c 可缓存为

const c = obj.a.b.c)

11. JavaScript开发中如何避免内存泄漏

内存泄漏是指:程序中已分配的内存,由于某种原因无法被垃圾回收机制回收,导致内存占用持续升高,最终可能引发页面卡顿、崩溃等问题。JS 中避免内存泄漏的核心是「及时释放无用资源,避免无

用引用的存在」,核心方案如下:

  1. 及时清除DOM元素的引用

◦ 当 DOM 元素被移除(如删除节点、组件卸载)时,要清除对该 DOM 元素的所有手动引用(如

全局变量、对象属性中的引用)

Code block

1// 不良实践:全局变量保留了DOM引用,DOM移除后内存无法释放

7document.body.removeChild(box);

8box = null; // 清空引用,垃圾回收机制可回收该内存

  1. 及时清除事件监听

◦ 当组件卸载或元素移除时,要手动移除对应的事件监听,避免事件监听残留导致的内存泄漏

Code block

1// 组件挂载时绑定事件 2const handleClick = () => console.log('click');

3document.addEventListener('click', handleClick);

4 5// 组件卸载时移除事件监听

6document.removeEventListener('click', handleClick);

◦ Vue/React 中:在组件销毁生命周期(Vue beforeDestroy / unmounted、React

componentWillUnmount / useEffect 清除函数)中清除事件监听

  1. 避免使用全局变量,合理管理变量作用域

◦ 避免无意识创建全局变量(如未声明的变量、函数内部 this 指向全局)

◦ 使用块级作用域( let / const)替代 var,变量超出作用域后会自动释放引用

  1. 及时清除定时器(setTimeout/setInterval)

◦ 定时器未清除会一直保留引用,即使组件已卸载,定时器仍会执行,导致内存泄漏

Code block

1// 组件挂载时创建定时器 2const timer = setInterval(() => {

3console.log('timer running');

4}, 1000);

5 6// 组件卸载时清除定时器

7clearInterval(timer);

  1. 避免闭包滥用,及时释放闭包引用

◦ 闭包会保留对外部函数变量的引用,若闭包被长期持有,外部函数变量无法被回收

◦ 当闭包不再使用时,手动清空闭包引用

全站分卷索引 · 7 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷