Lazy Load

Loads data or code only when absolutely necessary.



Usage in JavaScript:
medium


Fundamentals


The Lazy Load pattern allows you to load data or code only when absolutely necessary. It is designed to limit the use of resources such as memory, CPU cycles, and/or network traffic. It is a very helpful technique in providing end-users with a better experience, for example, faster display results when multiple items need to be displayed but only a few will do initially. An alternative name for this pattern is Just-in-Time Pattern.

There are two variations of this pattern: Lazy Initialization and the Ghost Pattern. Lazy initialization occurs when an object is lazily loaded. Initially the object will be null or undefined. Upon requesting the object the code checks if the object exists and if it doesn't then it loads it and returns its reference. Here is an example:

var employee = {

    name: "Victor",
    salaryHistory: null,

    getSalaryHistory: function () {
       if (this.salaryHistory === null) {                 // Lazy initializion
           this.salaryHistory = this.initializeHistory();
       } 
       return this.salaryHistory;
    },

    initializeHistory: function () {
        var history = {};
        history [2009] = "$34,000";
        history [2010] = "$36,500";
        history [2011] = "$44,000";
        history [2012] = "$45,500";
        history [2013] = "$51,000";
        return history;
    }
};

var history = employee.getSalaryHistory();

alert("2010: " + history[2010]);   // => 2010: $36,500
Run

The employee object is initially created without salary history. Perhaps this data is used infrequently and with many employees you can save yourself some significant memory and server access. In case the end-user needs salary data for employee Victor then the getSalaryHistory method checks if it is already loaded; if not, it will load it up and returns the array with historical salary data. It loads the data only when absolutely necessary.

The second variety called Ghost Pattern is rather interesting. A Ghost object is one that is only partially loaded and when called upon will load itself completely.

An example where the Ghost Pattern will be helpful is a web page that displays a long list of employees. For each employee you have a partially populated employee object with only the id, name, and thumbnail image loaded. These are 'ghost' versions of the fully loaded employee objects.

To get the full details on an employee, the end-user clicks on the employee image. At that time the ghost object starts loading itself up with the remaining data to turn itself into a fully populated employee object. This loading most likely takes place via an Ajax call in which the full employee record is retrieved from a back-end database. Here is what this looks like:

var Employee = function (id, name, thumbnail) {
    this.id = id; 
    this.name = name;
    this.thumbnail = thumbnail; 

    this.ghost = true;

    this.getDepartment = function () {
        if (this.ghost) this.load();
        return this.department;
    },
    this.getSalary = function () {
        if (this.ghost) this.load();
        return this.salary;
    }
    this.getBenefits = function () {
        if (this.ghost) this.load();
        return this.benefits;
    }

    this.load = function () {

        // load using an ajax call

        this.department = "Product Development";
        this.salary = "$66,400";
        this.benefits = "401(k); 21 vacation days";

        this.ghost = false;
    };
};

var employee = new Employee(211, "Nicolas Vick", "vick.jpg");

alert(employee.name);

// get more details on employee..

alert(employee.getDepartment());            // this is when it loads
alert(employee.getSalary());                // fully loaded
alert(employee.getBenefits());              // fully loaded


Run

This code does not account for the asynchronous nature of Ajax. It requires some sort of callback mechanism. But, you get the idea. The beauty of the Ghost Pattern is that it is usually totally transparent to the client programmer.

Of course, you have to balance the initial performance of loading the entire page versus a slower display of employee details. There are smart techniques that predict which employees are likely to require details and data for these can be pre-fetched, so some sort of balance is found between initial fast performance (for entire employee list) and later fast performance (for employee detail). All this depends on your particular situation.



Multiton