javaScript lazy load function

Due to browser differences, most js code contains a large number of if statements to guide the program to execute correctly.
Examples are as follows:

   function createXHR() {
        if (typeof XMLHttpRequest != "undefined") {
            return new XMLHttpRequest(); //Returns an instance of XMLHttpRequest when the XMLHttpRequest type is not undefined
        } else if (typeof ActiveXObject != "undefined") {
            if (typeof arguments.callee.activeXString != "string") {
                var version = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", ],
                    i;
                for (i = 0, i < version.length; i++) {
                    try {
                        new ActiveXObject(version[i]);
                        arguments.callee.activeXString = version[i];
                        break;
                    } catch (ex) {
                        // skip
                    }
                }
            }
            return new ActiveXObject(arguments.callee.activeXString);
        } else {
            throw new Error("NO XHR object available")
        }
    }

Every time createXHR() is called, it checks the browser's ability to support it.
First check the built-in XHR, and then test if there is an ActiveX-based XHR, neither of which throws an error.
This happens every time this function is called, and if the result of the branch does not change every time it is called, the if statement is executed.
If the browser supports built-in XHR, that means it will always support it, then this test is unnecessary, because the function of the if statement is slower than that without the if statement;
So if the if statement doesn't have to be executed every time, the code runs faster, and the solution is the lazy loading technique.

Lazy Loading

Represents that a branch of a function's execution will only be executed once (at the expense of a little performance when branch code is executed)
There are two ways to achieve lazy loading (both of which avoid executing unnecessary code):

Mode 1: Processing a function when it is called

During the first call, the changed function is overwritten to another function that is executed in the appropriate way so that no call to the original function passes through the branch that has already been executed.
The example is rewritten as follows:

function createXHR() {
        if (typeof XMLHttpRequest != "undefined") {
            createXHR = function () {
                return new XMLHttpRequest();
            };
        } else if (typeof ActiveXObject != "undefined") {
            createXHR = function () {
                if (typeof arguments.callee.activeXString != "string") {
                    var version = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", ],
                        i;
                    for (i = 0; i < version.length; i++) {
                        try {
                            new ActiveXObject(version[i]);
                            arguments.callee.activeXString = version[i];
                            break;
                        } catch (ex) {

                        }
                    }
                }
                return new ActiveXObject(arguments.callee.activeXString);
            }
        } else {
            createXHR = function () {
                throw new Error("NO XHL object available")
            };
        }
        return createXHR();
    }

In this lazily loaded createXHR(), each branch of the if statement assigns a value to the createXHR variable, overwriting the original function, and the last sentence is to call the newly assigned function. The next call will call the assigned function directly so that the if statement does not have to be executed again

Mode 2: When declaring a function, specify the appropriate function.

This way, you don't lose performance the first time you call a function, but a little performance the first time your code loads
The example is rewritten as follows:

var createXHR = (function () {
        if (typeof XMLHttpRequest != "undefined") {
            return function () {
                return new XMLHttpRequest()
            };
        } else if (typeof ActiveXObject != "undefined") {
            return function () {
                if (typeof arguments.callee.activeXString != "string") {
                    var version = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp", ],
                        i;
                    for (i = 0; i < version.length; i++) {
                        try {
                            new ActiveXObject(version[i]);
                            arguments.callee.activeXString = version[i];
                            break;
                        } catch (e) {
                            // 
                        }
                    }
                }
                return new ActiveXObject(arguments.callee.activeXString);
            };
        } else {
            return function () {
                throw new Error("NO XHR object available")
            };
        }
    })();

In this rewritten example, an anonymous, self-executing function is created to determine which function to use based on the results returned. The actual logic is the same. The difference is that the first line of code uses a var-defined function, and a new self-executing anonymous function is added. Each branch returns the correct function definition to assign it to createXHR().

Keywords: Javascript ECMAScript

Added by bradjinc on Thu, 21 Oct 2021 21:15:23 +0300