javascript

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

JavaScript Performance

JavaScript 性能优化

Micro-optimizations for high-performance JavaScript.
面向高性能JavaScript的微优化技巧。

Instructions

操作指南

1. Use Set for Lookups

1. 使用Set进行查找

typescript
// ❌ Bad - O(n) lookup
const ids = [1, 2, 3, 4, 5];
if (ids.includes(targetId)) { ... }

// ✅ Good - O(1) lookup
const idSet = new Set([1, 2, 3, 4, 5]);
if (idSet.has(targetId)) { ... }
typescript
// ❌ 不佳 - O(n) 查找时间
const ids = [1, 2, 3, 4, 5];
if (ids.includes(targetId)) { ... }

// ✅ 推荐 - O(1) 查找时间
const idSet = new Set([1, 2, 3, 4, 5]);
if (idSet.has(targetId)) { ... }

2. Use Map for Key-Value

2. 使用Map处理键值对

typescript
// ❌ Bad - object for dynamic keys
const cache: { [key: string]: Data } = {};
cache[key] = data;

// ✅ Good - Map for dynamic keys
const cache = new Map<string, Data>();
cache.set(key, data);
typescript
// ❌ 不佳 - 用对象处理动态键
const cache: { [key: string]: Data } = {};
cache[key] = data;

// ✅ 推荐 - 用Map处理动态键
const cache = new Map<string, Data>();
cache.set(key, data);

3. Early Returns

3. 提前返回

typescript
// ❌ Bad - nested conditions
function process(data) {
  if (data) {
    if (data.isValid) {
      if (data.type === 'user') {
        return handleUser(data);
      }
    }
  }
  return null;
}

// ✅ Good - early returns
function process(data) {
  if (!data) return null;
  if (!data.isValid) return null;
  if (data.type !== 'user') return null;
  return handleUser(data);
}
typescript
// ❌ 不佳 - 嵌套条件判断
function process(data) {
  if (data) {
    if (data.isValid) {
      if (data.type === 'user') {
        return handleUser(data);
      }
    }
  }
  return null;
}

// ✅ 推荐 - 提前返回
function process(data) {
  if (!data) return null;
  if (!data.isValid) return null;
  if (data.type !== 'user') return null;
  return handleUser(data);
}

4. Avoid Creating Arrays

4. 避免创建中间数组

typescript
// ❌ Bad - creates intermediate array
const result = items.filter(x => x.active).map(x => x.name)[0];

// ✅ Good - find first match
const result = items.find(x => x.active)?.name;
typescript
// ❌ 不佳 - 生成中间数组
const result = items.filter(x => x.active).map(x => x.name)[0];

// ✅ 推荐 - 直接查找首个匹配项
const result = items.find(x => x.active)?.name;

5. Batch DOM Updates

5. 批量更新DOM

typescript
// ❌ Bad - multiple reflows
items.forEach(item => {
  const el = document.createElement('div');
  el.textContent = item.name;
  container.appendChild(el);
});

// ✅ Good - single reflow
const fragment = document.createDocumentFragment();
items.forEach(item => {
  const el = document.createElement('div');
  el.textContent = item.name;
  fragment.appendChild(el);
});
container.appendChild(fragment);
typescript
// ❌ 不佳 - 触发多次重排
items.forEach(item => {
  const el = document.createElement('div');
  el.textContent = item.name;
  container.appendChild(el);
});

// ✅ 推荐 - 仅触发一次重排
const fragment = document.createDocumentFragment();
items.forEach(item => {
  const el = document.createElement('div');
  el.textContent = item.name;
  fragment.appendChild(el);
});
container.appendChild(fragment);

6. Passive Event Listeners

6. 被动事件监听器

typescript
// ✅ Use passive for scroll/touch events
element.addEventListener('scroll', handler, { passive: true });
element.addEventListener('touchstart', handler, { passive: true });
typescript
// ✅ 为滚动/触摸事件使用被动监听器
element.addEventListener('scroll', handler, { passive: true });
element.addEventListener('touchstart', handler, { passive: true });

7. Caching Expensive Operations

7. 缓存高开销操作

typescript
// ✅ Memoization
const cache = new Map();

function expensiveCalculation(input: string) {
  if (cache.has(input)) {
    return cache.get(input);
  }
  const result = /* expensive operation */;
  cache.set(input, result);
  return result;
}
typescript
// ✅ 记忆化缓存
const cache = new Map();

function expensiveCalculation(input: string) {
  if (cache.has(input)) {
    return cache.get(input);
  }
  const result = /* 高开销操作 */;
  cache.set(input, result);
  return result;
}

8. Object Spread vs Object.assign

8. 对象展开 vs Object.assign

typescript
// ✅ For small objects - spread is fine
const merged = { ...a, ...b };

// ✅ For large objects - Object.assign is faster
const merged = Object.assign({}, a, b);
typescript
// ✅ 小型对象 - 展开语法即可
const merged = { ...a, ...b };

// ✅ 大型对象 - Object.assign速度更快
const merged = Object.assign({}, a, b);

References

参考资料