惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
I
InfoQ
B
Blog
Engineering at Meta
Engineering at Meta
Y
Y Combinator Blog
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
量子位
The Cloudflare Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
小众软件
小众软件
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 司徒正美
美团技术团队
人人都是产品经理
人人都是产品经理
博客园 - 三生石上(FineUI控件)
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
罗磊的独立博客
博客园 - 聂微东
IT之家
IT之家

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
JavaScript Performance: 8 Fixes That Actually Matter (2026)
Alex Chen · 2026-05-19 · via DEV Community

Alex Chen

JavaScript Performance: 8 Fixes That Actually Matter (2026)

Not all optimizations are worth your time. These 8 are.

The Hierarchy of Performance

Before optimizing, ask:
1. Is anyone actually complaining about speed?
2. Have you measured where the slowdown is?
3. Is this optimization worth the complexity?

Rule of thumb: Optimize the hot path first.

Enter fullscreen mode Exit fullscreen mode

Fix #1: Debounce and Throttle User Events

The #1 performance mistake I see: running expensive operations on every keystroke/scroll.

// ❌ BAD — Runs on every keystroke
input.addEventListener('input', (e) => {
  searchAPI(e.target.value); // API call on every key press!
});

// ✅ GOOD — Waits until user stops typing
function debounce(fn, delay = 300) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

input.addEventListener('input', debounce((e) => {
  searchAPI(e.target.value);
}, 300));

// ✅ GOOD — Runs at most once per interval (for scroll/resize)
function throttle(fn, interval = 100) {
  let lastTime = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastTime >= interval) {
      lastTime = now;
      fn(...args);
    }
  };
}

window.addEventListener('scroll', throttle(checkScrollPosition, 100));

Enter fullscreen mode Exit fullscreen mode

Impact: Can reduce function calls from thousands to dozens per second.

Fix #2: Lazy Load Images and Components

<!-- Just add loading="lazy" -->
<img src="photo.jpg" alt="..." loading="lazy" width="800" height="600">

<!-- For background images or dynamic content -->
<div data-src="heavy-image.jpg" class="lazy"></div>

Enter fullscreen mode Exit fullscreen mode

// Intersection Observer (no library needed)
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const el = entry.target;
      if (el.dataset.src) el.src = el.dataset.src;
      if (el.dataset.style) el.style.backgroundImage = `url(${el.dataset.style})`;
      el.classList.add('loaded');
      observer.unobserve(el);
    }
  });
}, { rootMargin: '100px' }); // Start loading 100px before visible

document.querySelectorAll('.lazy').forEach(el => observer.observe(el));

Enter fullscreen mode Exit fullscreen mode

Impact: Reduces initial page load by 30-70% for image-heavy pages.

Fix #3: Use requestAnimationFrame for Visual Updates

// ❌ BAD — May cause layout thrashing
function updatePosition() {
  element.style.left = calculateNewX();
  element.style.top = calculateNewY();
  requestAnimationFrame(updatePosition);
}

// ✅ GOOD — Syncs with browser's paint cycle
function updatePosition() {
  const x = calculateNewX();
  const y = calculateNewY();

  requestAnimationFrame(() => {
    element.style.transform = `translate(${x}px, ${y}px)`;
  });

  requestAnimationFrame(updatePosition);
}

Enter fullscreen mode Exit fullscreen mode

Also use requestIdleCallback for non-urgent work:

// Do heavy work when browser is idle
requestIdleCallback(deadline => {
  while (deadline.timeRemaining() > 0 && tasks.length > 0) {
    processTask(tasks.shift());
  }
});

Enter fullscreen mode Exit fullscreen mode

Fix #4: Avoid Layout Thrashing

Layout thrashing = forcing browser to recalculate layout repeatedly.

// ❌ BAD — Reads/writes in loop (forces reflow each iteration)
elements.forEach(el => {
  console.log(el.offsetHeight);  // READ → forces reflow
  el.style.width = el.offsetWidth + 10 + 'px';  // WRITE → then read again
});

// ✅ GOOD — Batch reads, then batch writes
// First: all reads
const heights = elements.map(el => el.offsetHeight);

// Then: all writes
elements.forEach((el, i) => {
  el.style.width = heights[i] + 10 + 'px';
});

Enter fullscreen mode Exit fullscreen mode

Tools: Chrome DevTools → Rendering → "Paint flashing" to see repaints.

Fix #5: Efficient DOM Manipulation

// ❌ BAD — Multiple DOM insertions
const list = document.getElementById('list');
items.forEach(item => {
  const li = document.createElement('li');
  li.textContent = item.name;
  list.appendChild(li);  // Reflow each time
});

// ✅ GOOD — Single insertion with DocumentFragment
const fragment = new DocumentFragment();
items.forEach(item => {
  const li = document.createElement('li');
  li.textContent = item.name;
  fragment.appendChild(li);
});
list.appendChild(fragment);  // Single reflow

// ✅ BETTER — innerHTML (for simple cases)
list.innerHTML = items.map(item => 
  `<li>${escapeHtml(item.name)}</li>`
).join('');

Enter fullscreen mode Exit fullscreen mode

For frequent updates, consider Virtual DOM libraries or template literals with smart diffing.

Fix #6: Optimize Loops

const arr = [/* 10,000+ items */];

// ❌ SLOW — forEach with callback overhead
arr.forEach(item => { /* ... */ });

// ❌ SLOWER — for...of (iterator protocol overhead)
for (const item of arr) { /* ... */ };

// ✅ FASTEST — Traditional for loop (for hot paths)
for (let i = 0; i < arr.length; i++) {
  const item = arr[i];
  // ...
}

// ✅ ALSO FAST — Length cached (if array might change)
for (let i = 0, len = arr.length; i < len; i++) {
  // ...
}

Enter fullscreen mode Exit fullscreen mode

Reality check: For most apps, this difference is negligible. Only optimize loops that run 10,000+ times per second.

Fix #7: Memoize Expensive Computations

// Simple memoization
function memoize(fn) {
  const cache = new Map();
  return (...args) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) return cache.get(key);
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}

// Usage
const expensiveCalculation = memoize((n) => {
  console.log('Computing...');
  return n * n * n; // Imagine this is slow
});

expensiveCalculation(5); // "Computing..." → 125
expensiveCalculation(5); // → 125 (from cache!)
expensiveCalculation(5); // → 125 (from cache!)

// React equivalent: useMemo / React.memo
const ExpensiveComponent = React.memo(({ data }) => {
  const result = useMemo(() => processData(data), [data]);
  return <div>{result}</div>;
});

Enter fullscreen mode Exit fullscreen mode

Fix #8: Web Workers for Heavy Computation

// main.js
const worker = new Worker('worker.js');

worker.postMessage({ type: 'PROCESS', data: largeDataset });

worker.onmessage = (e) => {
  if (e.data.type === 'RESULT') {
    renderResults(e.data.result);
  }
};

// worker.js
self.onmessage = (e) => {
  if (e.data.type === 'PROCESS') {
    const result = heavyComputation(e.data.data);
    self.postMessage({ type: 'RESULT', result });
  }
};

Enter fullscreen mode Exit fullscreen mode

Use for: Image processing, crypto operations, large dataset analysis, real-time calculations.

What NOT To Optimize

❌ Don't optimize:
   • Code readability for marginal gains
   • One-time operations (startup, config loading)
   • Code that runs < 10ms total
   • Before measuring (you'll guess wrong 80% of the time)

✅ DO optimize:
   • Render loops (animation, scroll handlers)
   • Large list rendering (virtualize instead)
   • API response processing (big JSON payloads)
   • Event handlers that fire frequently
   • Anything users complain about being "slow"

Enter fullscreen mode Exit fullscreen mode

Measuring Performance

// Quick measurement
console.time('operation');
doSomething();
console.timeEnd('operation'); // operation: 123ms

// More precise
const start = performance.now();
doSomething();
const duration = performance.now() - start;
console.log(`Took ${duration.toFixed(2)}ms`);

// In production: Performance Observer
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.duration > 100) {
      logSlowOperation(entry.name, entry.duration);
    }
  }
});
observer.observe({ entryTypes: ['measure'] });

Enter fullscreen mode Exit fullscreen mode


What's the biggest performance win you've ever found?

Follow @armorbreak for more practical JS guides.