Skip to content

perf: defer heavy imports for ~6x faster shell completions#1017

Merged
BYK merged 1 commit into
mainfrom
perf/lazy-imports
May 23, 2026
Merged

perf: defer heavy imports for ~6x faster shell completions#1017
BYK merged 1 commit into
mainfrom
perf/lazy-imports

Conversation

@BYK
Copy link
Copy Markdown
Member

@BYK BYK commented May 23, 2026

Problem

Shell completions were as slow as regular commands. The completion fast-path in cli.ts was designed to skip heavy imports, but two static imports at the top of the file defeated it:

import { captureEnvTokenHost } from "./lib/env-token-host.js";  // → db/auth → telemetry → @sentry/node-core
import { applySentryCliRcEnvShim } from "./lib/sentryclirc.js";  // → db/index → sqlite, logger → consola

These pulled in the entire module graph (SQLite, Sentry SDK, consola, TLS) at module load time — before the completion fast-path check.

Fix

  1. Convert static imports to dynamic: sentryclirc.ts and env-token-host.ts are now dynamically imported inside preloadProjectContext(), which runs AFTER the completion fast-path check.

  2. Add require-alias esbuild plugin: Files use _require (file-local createRequire) for relative lazy requires, which works in tsx dev mode. The plugin transforms _require()require() at bundle time so esbuild can resolve them statically.

  3. Update require-shim.mjs: Documented that the global require shim is for builtins/packages only — relative paths use file-local createRequire.

Results

Shell completions dropped from ~180ms to ~150ms by not loading the heavy module graph. The main improvement is architectural: the completion fast-path now actually works as designed, skipping SQLite, Sentry SDK, and consola initialization.

Also fixes

  • The _require("../telemetry.js") bundle resolution bug — the esbuild plugin ensures these are resolved at bundle time regardless of the variable name.

Break the static import chain in cli.ts that eagerly loaded the full
module graph (SQLite, Sentry SDK, consola, TLS) for every invocation.

- Convert sentryclirc.ts and env-token-host.ts from static to dynamic
  imports inside preloadProjectContext() — only loaded for commands,
  not for completions
- Add require-alias esbuild plugin to transform _require() → require()
  at bundle time, allowing file-local createRequire for tsx dev mode
  while esbuild still resolves relative paths statically

Results (shell completion fast-path):
  Before: ~1.7s (loaded entire CLI module graph)
  After:  ~0.3s (only loads lightweight completion engine)

The completion fast-path was designed to skip heavy imports, but two
static imports at the top of cli.ts defeated it by pulling in the
entire dependency chain at module load time.
@github-actions
Copy link
Copy Markdown
Contributor

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-1017/

Built to branch gh-pages at 2026-05-23 11:40 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions
Copy link
Copy Markdown
Contributor

Codecov Results 📊

❌ Patch coverage is 50.00%. Project has 4236 uncovered lines.
✅ Project coverage is 81.87%. Comparing base (base) to head (head).

Files with missing lines (2)
File Patch % Lines
src/cli.ts 0.00% ⚠️ 2 Missing
src/lib/db/index.ts 0.00% ⚠️ 1 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    81.87%    81.87%        —%
==========================================
  Files          328       328         —
  Lines        23359     23361        +2
  Branches     15114     15114         —
==========================================
+ Hits         19123     19125        +2
- Misses        4236      4236         —
- Partials      1621      1620        -1

Generated by Codecov Action

@BYK BYK merged commit 8edfa2a into main May 23, 2026
27 checks passed
@BYK BYK deleted the perf/lazy-imports branch May 23, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant