Lazy Object Initialization
The Firefox DevTools underlying code, which is written with JavaScript and HTML, is a complex application. Due to the complexity and amount of work going on, the DevTools team has done everything they can to load as little as possible. Furthermore the team has a system of lazily importing and initializing objects when they're needed. I've taken a bit of time to reduce the initializer, let's take a look!
The system relies on taking advantage of Object.defineProperty's get function to initialize an object when needed:
// Lazily initializes an object's property until it's used
function lazyGet(hostObj, name, initializer) {
let defined = false;
Object.defineProperty(hostObj, name, {
get: function () {
// If not already defined, define it by executing
// its initializer and setting it as value
if (!defined) {
defined = true;
// Overrides the original property definition
// which is the initializer
Object.defineProperty(hostObj, name, {
configurable: true,
enumerable: true,
value: initializer.apply(hostObj),
writable: true,
});
return hostObj[name];
}
},
configurable: true,
enumerable: true
});
}
With the lazyGet function, the property you want is only initialized and processing down when its getter is called:
// Don't define window.myProp until someone tries to use it
// Thus, if it's never used, it's never initialized
lazyGet(window, "myProp", () => {
return { message: "Hello!" };
});
// window.myProp is now undefined, since it hasn't been requested yet
// Use it for something, which triggers initialization and returns its value
console.log(window.myProp.message);
// Using it again doesn't initialize again, since it was already created
console.log(window.myProp.message);
// And it can be reassigned later on:
window.myProp = null;
Mozilla's initializer is much more complex as it also acts as a loader, but you get the idea. We always think about lazy loading resources but it's also good to think about initializing properties as they may not be needed! Keep a tiny footprint if you can!





This is a nice idea. I think a better example to demonstrate lazy initialization might be: