Web performancce optimization: JS execution efficiency optimization in practice: throttling, debouncing, and lazy execution the correct way

When does your web page lag behind? Does the input field take too long to respond? You click a button, and it executes three actions?

You suspect it's a performance issue, but maybe it's just the way JavaScript handles events.

Frontend performance optimization isn't just about "minimizing the package"; it's also about ensuring smooth execution flow.

This article focuses on JS execution performance, exploring three angles: throttling, debouncing, and lazy execution. We'll discuss their principles, use cases, and best practices.

**One: JS execution performance issues: Are they caused by events?

JavaScript runs on a single thread, meaning:

  • It can only perform one action at a time.
  • If JS execution is slow, it blocks rendering and response.

Common lag scenarios:

**Scenario **Symptom
Scroll binding with onScroll, triggering once per pixel Page lag significantly
Input field binding with onInput to perform a search Every keystroke sends a request
Layout re-rendering on page resize Browser resizing causes unbearable lag

We need an approach—don't rush to act immediately.

**Two: Throttling vs. Debouncing: What's the difference?

Throttling:

Definition: Execute the function once every set time

Use case: Scenarios where you want to "time out" before executing an action, such as scrolling, window resize, or mouse movement.

JavaScript implementation:

function throttle(fn, delay) {
  let timer = null;
  return function (...args) {
    if (!timer) {
      timer = setTimeout(() => {
        fn.apply(this, args);
        timer = null;
      }, delay);
    }
  };
}

Usage example:

window.addEventListener('scroll', throttle(() => handleScroll(), 100));

Debouncing:

Definition: Execute the function only after the event has stopped for a set period

Use case: Scenarios where you want to execute the function after the user has completed an action, such as search input, form validation, or button clicks.

JavaScript implementation:

function debounce(fn, delay) {
  let timer = null;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

Usage example:

input.addEventListener('input', debounce(() => handleInput(), 300));

Key Tip: Remember this rule of thumb:

  • Rolling or sliding actions (e.g., scroll, input) → Use throttling
  • Clicks or key presses → Use debouncing
  • If unsure, try debouncing and measure the user experience

Three: Lazy Execution: Do things when needed, not all at once

"Lazy execution" is a virtue in performance optimization.

1. Lazy DOM rendering: Load content only when needed

Avoid initializing all tab content immediately. Load content after the user triggers it:

function showTab(index) {
  if (!document.querySelector(`#tab${index}`)) {
    renderTab(index);
  }
}

2. Lazy loading of modules (code-level laziness)

const loadEditor = () => import('./RichEditor.vue');

Pair this with dynamic routing and conditional rendering to achieve efficient performance control.

Four: Modern Recommendations: Using lodash and requestIdleCallback

Lodash-based solutions:

import { debounce, throttle } from 'lodash-es';

element.addEventListener('scroll', throttle(() => doSomething(), 100));
  • Pros: Performant, concise, and offers cancelable functionality
  • Cons: Requires proper initialization

requestIdleCallback: Let the browser say "I'm done; come back later"

requestIdleCallback(() => {
  // Perform tasks like statistics reporting or background data loading
});

ideal for scenarios where you want to execute non-critical tasks without blocking the UI.

Note on Compatibility:

Ensure browser compatibility when using the requestIdleCallback function, as older browsers may require adjustments.

Five: Recommendations for Monitoring JS Execution Performance

Use Chrome DevTools → Performance → Flame Chart:

  • Analyze function execution time
  • Check for blocked主线程
  • Identify high-frequency code and layout reordering

Summary: Faster to write, but execution efficiency counts

JS performance isn't just about how fast a function runs in a single execution; it's about how smoothly it runs over time.

Key Takeaways:

  • Throttling is for periodic tasks (e.g., scrolling, resize, mouse movement)
  • Debouncing is for user-initiated actions (e.g., input, click)
  • Lazy execution is for tasks that don't need immediate attention
  • Optimizing execution efficiency means reducing unnecessary calculations and improving workflow

Your page not only opens quickly but also responds swiftly.

Thẻ: js performance optimization Web Development Event Handling lazy execution

Đăng vào ngày 4 tháng 7 lúc 16:05