refactor: lazy-load webview panel modules via shared cache#66
Open
CompN3rd wants to merge 2 commits into
Open
Conversation
Decouple PlanningPanel, PrDetailsPanel, PipelineRunDetailsPanel from the activation import graph. Each is now reached via a shared lazyPanels.ts loader that caches the dynamic import promise so all callers observe the same loaded-or-not state. This matters for static refresh methods (refreshAllOpenPanels, refreshOpenPanels) which must no-op when the module was never opened; they consult *PanelLoaded() instead of forcing a load. Honest scoping note: the extension host bundle is currently CJS without splitting, so esbuild inlines dynamic imports as wrapped require() calls and the modules are still parsed at activation. This change is purely structural and unblocks a future move to ESM + splitting (or manual external chunks) where the deferred parse would actually take effect.
There was a problem hiding this comment.
Pull request overview
Refactors webview panel entrypoints to be reached through a shared lazy-loader so extension.ts and command modules can coordinate “module has ever been requested” state and avoid loading panels solely to run no-op static refresh methods.
Changes:
- Added
src/views/lazyPanels.tswith cached dynamic-import loaders for Planning, PR Details, and Pipeline Run Details panels. - Updated
src/extension.tsto remove direct panel imports and to guard refresh calls behind*PanelLoaded()checks. - Updated PR/pipeline command handlers to load panel modules via the shared loader before calling
*.show().
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/views/lazyPanels.ts | Introduces shared cached dynamic-import loaders and “loaded” helpers for panel modules. |
| src/extension.ts | Replaces static panel imports with shared lazy loading and conditional refresh behavior. |
| src/commands/pullRequestCommands.ts | Loads PrDetailsPanel via shared loader before showing details panel. |
| src/commands/pipelineCommands.ts | Loads PipelineRunDetailsPanel via shared loader before showing run details panel. |
Comment on lines
+8
to
+17
| export const planningPanelLoaded = () => _planning; | ||
|
|
||
| let _prDetails: Promise<typeof import('./prDetailsPanel')> | undefined; | ||
| export const loadPrDetailsPanel = () => (_prDetails ??= import('./prDetailsPanel')); | ||
| export const prDetailsPanelLoaded = () => _prDetails; | ||
|
|
||
| let _pipelineRun: Promise<typeof import('./pipelineRunDetailsPanel')> | undefined; | ||
| export const loadPipelineRunDetailsPanel = () => | ||
| (_pipelineRun ??= import('./pipelineRunDetailsPanel')); | ||
| export const pipelineRunDetailsPanelLoaded = () => _pipelineRun; |
The reviewer flagged the old name as misleading: it returns the cached import promise iff loadXPanel() was previously called, not a boolean 'is loaded' state. New names follow the loadX / loadedX convention used elsewhere for lazy module accessors.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Decouples
PlanningPanel,PrDetailsPanel,PipelineRunDetailsPanelfrom the activation import graph. Each is now reached via a sharedsrc/views/lazyPanels.tsloader that caches the dynamic import promise so all callers observe the same loaded-or-not state.Why shared cache
Static refresh methods (
PrDetailsPanel.refreshAllOpenPanels,PlanningPanel.refreshOpenPanels) are invoked from config-change handlers and toggle commands that must no-op when the module was never opened. The cache lets these paths check*PanelLoaded()and skip the refresh entirely, instead of forcing a load just to discover there are no open panels.Inlining
await import('../views/prDetailsPanel')per call site would create one cache per importer, and the shared-state check inextension.tswould observe staleundefinedeven after the command path had already loaded and opened a panel — silent missed refresh.Honest scoping note
The extension host bundle is currently CJS without
splitting, so esbuild inlines dynamic imports as wrappedrequire()calls. The lazy modules are still parsed at activation today, so this PR does not improve activation time on its own.This change is purely structural and unblocks a future move to ESM + splitting (or manual external chunks via separate esbuild entries) where the deferred parse would actually take effect.
Verification
npm run compilecleannpm run lintcleanFiles
src/views/lazyPanels.tssrc/extension.ts— usesloadPlanningPanel,loadPipelineRunDetailsPanel,planningPanelLoaded,prDetailsPanelLoadedsrc/commands/pullRequestCommands.ts— usesloadPrDetailsPanelsrc/commands/pipelineCommands.ts— usesloadPipelineRunDetailsPanel