In the previous chapter, Availability Guardrails, we set up a "bouncer" to decide if the feedback command is allowed to run. We ensured that restricted environments don't even see the command.
Now, we face a performance challenge. Even if the command is allowed, do we really want to load all the code for it immediately when the application starts?
This brings us to Dynamic Command Loading.
Imagine a handyman arriving at a house. He has a massive truck filled with 500 different heavy power toolsβsaws, drills, jackhammers, and welders.
The Problem: If the handyman tries to stuff all 500 tools into his pockets before ringing the doorbell, two things happen:
The Solution: The handyman walks to the door with empty pockets. When the homeowner says, "I need to fix a shelf," then he goes to the truck, grabs the drill, and comes back.
The Use Case:
The feedback command uses a complex User Interface library (React). It is "heavy." If a user just wants to list their files, they shouldn't have to wait for the Feedback UI code to load. We want to keep that code in the "shed" until the user actually types feedback.
To achieve this "fetch-on-demand" behavior, we use a JavaScript feature called Dynamic Imports.
Usually, at the top of a file, you see Static Imports. These happen immediately when the program starts.
// Static Import: Loads immediately.
// "Carrying the tool in your pocket."
import { heavyTool } from './heavyTool.js';
However, we can also import files inside a function. This is a Dynamic Import.
// Dynamic Import: Loads only when this function runs.
// "Leaving the tool in the shed."
const loadTool = () => import('./heavyTool.js');
We implement this in our command definition file (index.ts) using the load property.
Inside our feedback object, we define a property called load. This is a function that returns the result of an import() call.
const feedback = {
// ... name, aliases, description ...
// The "Fetch from Shed" instruction
load: () => import('./feedback.js'),
}
Explanation:
() => ...: This is a function. It doesn't run automatically; it waits to be called.import('./feedback.js'): This tells the system to go find the file named feedback.js and load it into memory../feedback.js?You might notice we are importing a file we haven't looked at yet.
index.ts: The definition (The Menu Entry). Lightweight.feedback.js: The actual logic and UI (The Meal). Heavy.We separate the definition from the implementation so the definition is cheap to read.
Let's look at what happens "Under the Hood" when the application is running.
Walkthrough:
index.ts. This is very fast because it's just a small text object.feedback.load() function.
Let's look at the final piece of our index.ts file.
// File: index.ts
// ... previous properties (name, isEnabled) ...
// This is the implementation of Dynamic Loading
load: () => import('./feedback.js'),
} satisfies Command
export default feedback
Explanation:
load, we ensure that if the user never types "feedback", we never pay the cost of loading that code.satisfies Command: This ensures our object matches the expected structure. If we forgot the load function, TypeScript would warn us here because a command isn't useful if it can't be loaded!In this chapter, we learned about Dynamic Command Loading.
We solved the problem of slow application startup by:
import()) instead of static imports.load function that is only called when the user explicitly requests the command.
Now we have the Definition (index.ts) and we know how to load the Implementation (feedback.js). But what exactly is inside that heavy file we just loaded? How does the application know where to start running code inside that new file?
In the next chapter, we will open up feedback.js and look at the entry point of our feature.
Next Chapter: LocalJSX Execution Entry Point
Generated by Code IQ