In the previous chapter, Feature Gating (Statsig), we implemented a security system. We ensured that only authorized users (those with the tengu_thinkback permission) could access our command.
Now we have a different problem: Performance.
Imagine a car factory.
This is exactly what happens to software if we aren't careful.
The Problem: If our CLI has 50 different commands, and we load the code for all of them when the program starts, the user has to wait several seconds just to see the blinking cursor.
The Goal: We want a "Just-in-Time" delivery system. We want the CLI to load the heavy code for
thinkback-playonly at the exact moment the user tries to run it.
To solve this, we use a technique called Lazy Loading.
In TypeScript/JavaScript, there are two ways to bring in code from other files.
import ... from ....import(...).For our CLI to be fast, we want to avoid option #1 for our command logic.
We implement Lazy Loading inside our registration object in index.ts.
Normally, you might be tempted to do this:
// β BAD for performance
// This loads the heavy code immediately!
import { call } from './thinkback-play.js'
const thinkbackPlay = {
name: 'thinkback-play',
run: call // The code is already here, occupying memory
}
load Property
Instead, we use a special property in our command object called load. We give it a function that returns a Dynamic Import.
// β
GOOD for performance
// No heavy imports at the top!
const thinkbackPlay = {
name: 'thinkback-play',
// Only runs when the CLI specifically calls this function
load: () => import('./thinkback-play.js'),
}
() => ... acts like a pause button. The code inside it (import(...)) does not run until someone actually presses that button (executes the function).Let's visualize the timeline. Notice how the heavy file is ignored until the very end.
Let's look at index.ts again. We've looked at type, name, and isEnabled. Now let's focus on the load property.
// From index.ts
const thinkbackPlay = {
// ... other properties (type, name, isEnabled)
// The Lazy Loader:
load: () => import('./thinkback-play.js'),
} satisfies Command
satisfies Command?
You might see satisfies Command at the end of the object. This is a TypeScript feature.
It ensures that our object has all the required parts (like name and load). If we forgot to write the load function, TypeScript would give us a red error line here.
When the import() finishes, it looks for the file ./thinkback-play.js.
// From thinkback-play.ts
// The CLI expects this specific function name "call"
export async function call(): Promise<LocalCommandResult> {
// Heavy logic starts here...
const v2Data = loadInstalledPluginsV2()
return { type: 'success' } // simplified
}
import() statement imports the entire file. The CLI framework is smart enough to look inside that imported file, find the exported function named call, and execute it.In this chapter, we learned how to keep our application fast using Lazy Loading.
We learned:
load: () => import(...) to delay loading until necessary.Now our command is:
However, once the code loads, it needs to know what to play. It needs to know about the environment it is running in. Does the user have specific plugins installed? Where are the files located?
To handle this, we need Context-Aware Configuration.
Next Chapter: Context-Aware Configuration
Generated by Code IQ