Frontend Patterns

Pattern

Lazy Initialization

Defer expensive state calculations until the first render when they're needed.

State Management Intermediate

Lazy Initialization

Problem

State initialization runs expensive calculations on every component mount, even when recreating the same values. Reading from localStorage, parsing JSON, or filtering large arrays happens repeatedly during development with hot reloads. Component instantiation becomes a performance bottleneck as initialization logic grows.

Solution

Defer expensive operations until their results are actually needed rather than computing them upfront. This improves initial load time by spreading work across the user’s session.

Example

This example shows how to defer parsing localStorage data until it’s actually needed using a getter, rather than doing it immediately in the constructor.

// Framework-agnostic lazy initialization
class Component extends HTMLElement {
  constructor() {
    super();
    // Don't initialize expensive state in constructor
    // Keep constructor fast and lightweight
  }

  get data() {
    // Lazy initialization - only runs once when first accessed
    if (!this._data) {
      // Parse localStorage only when someone accesses this.data
      this._data = JSON.parse(localStorage.getItem('data'));
    }
    return this._data;
  }

  connectedCallback() {
    // Data is only parsed when needed (when this.data is accessed)
    this.innerHTML = `<div>${this.data}</div>`;
  }
}

Benefits

  • Improves performance by running expensive calculations only once on first render.
  • Reduces wasted work during hot reloads in development.
  • Speeds up component instantiation by deferring initialization.
  • Particularly valuable for reading from localStorage or parsing JSON.

Tradeoffs

  • Adds syntax complexity with function initializers instead of direct values.
  • Can be misused, hiding expensive operations that should be optimized differently.
  • May delay the performance cost to first render instead of eliminating it.
  • Not needed for simple, inexpensive default values.
Stay Updated

Get New Patterns
in Your Inbox

Join thousands of developers receiving weekly insights on frontend architecture patterns

No spam. Unsubscribe anytime.