一、代码层面的优化
-
减少不必要的操作
-
避免重复计算:在循环中将不变的值缓存到变量中。
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); }
-
-
高效使用循环
-
优先使用
for
或while
循环而非forEach
(大数据量时更明显)。 -
倒序循环(
i--
)可能略微提升性能(减少条件判断次数)。
-
-
事件委托
-
利用事件冒泡,减少事件监听器数量:
javascript
复制
下载
// 优化前:为每个按钮绑定事件 document.querySelectorAll('button').forEach(btn => { btn.addEventListener('click', handleClick); }); // 优化后:委托到父元素 document.getElementById('parent').addEventListener('click', (e) => { if (e.target.tagName === 'BUTTON') handleClick(e); });
-
二、数据存取优化
-
作用域链与原型链
-
减少深层作用域链查找,优先使用局部变量。
-
避免过深的原型链访问(如
obj.a.b.c.d
),可通过中间变量缓存。
-
-
数据结构选择
-
高频查询场景使用
Map
/Set
替代Object
(哈希表效率更高)。 -
使用
TypedArray
处理二进制数据(如 WebGL、Canvas)。
-
三、DOM 操作优化
-
减少 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
),触发强制重排。
-
-
减少重排(Reflow)与重绘(Repaint)
-
使用
transform
和opacity
实现动画(触发 GPU 加速)。 -
集中样式修改:通过修改
class
而非逐行修改style
。 -
使用
requestAnimationFrame
优化动画:
javascript
复制
下载
function animate() { element.style.left = `${pos}px`; pos++; requestAnimationFrame(animate); }
-
四、内存管理
-
避免内存泄漏
-
及时解绑无用的事件监听器、定时器。
-
避免意外的闭包引用:
javascript
复制
下载
// 错误示例:闭包引用大对象 function init() { const largeData = new Array(1e6).fill('data'); document.getElementById('btn').addEventListener('click', () => { console.log(largeData); // largeData 无法释放! }); }
-
清除无效的 DOM 引用(如已移除元素的缓存)。
-
-
使用弱引用
-
通过
WeakMap
/WeakSet
管理临时关联数据,避免阻止垃圾回收。
-
五、网络与加载优化
-
减少脚本体积
-
代码压缩(Terser)、Tree Shaking 删除无用代码。
-
按需加载:使用动态
import()
或代码分割(Webpack/Rollup)。
javascript
复制
下载
// 动态导入 button.addEventListener('click', async () => { const module = await import('./heavy-module.js'); module.run(); });
-
-
合理加载脚本
-
使用
defer
或async
属性避免阻塞渲染。
html
复制
下载
运行
<script src="app.js" defer></script> <!-- 延迟执行,不阻塞 DOM 解析 --> <script src="analytics.js" async></script> <!-- 异步加载,执行时机不确定 -->
-
-
利用浏览器缓存
-
设置
Cache-Control
/ETag
响应头缓存静态资源。 -
使用 Service Worker 实现离线缓存(PWA)。
-
六、异步与并行
-
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); };
-
-
合理使用微任务与宏任务
-
优先使用
Promise
/queueMicrotask
而非setTimeout(fn, 0)
。
-
七、工具与监控
-
性能分析工具
-
Chrome DevTools 的 Performance 面板分析运行时性能。
-
Memory 面板检测内存泄漏。
-
Lighthouse 生成性能优化报告。
-
-
性能监控
-
使用
PerformanceObserver
API 监控关键指标(如首次输入延迟、长任务)。
javascript
复制
下载
const observer = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { console.log('长任务:', entry); } }); observer.observe({ entryTypes: ['longtask'] });
-
总结
性能优化需结合具体场景权衡,核心思路是:
-
减少计算量:优化算法复杂度(如 O(n²) → O(n))。
-
减少 I/O 操作:包括 DOM 操作、网络请求。
-
并行化:利用 Web Workers、异步任务。
-
内存友好:及时释放无用资源,避免泄漏