Latest Results
perf(tsconfig): reuse cached lstat to avoid redundant stat in get_tsconfig (#1238)
## Problem
While tracing every `FileSystem` syscall during resolve, module
resolution turned out to be redundancy-free (cold + warm), but
**tsconfig loading double-stats every config file**.
`Cache::get_tsconfig` classifies the config path with `fs.metadata` (a
`stat`) to decide file-vs-dir, then canonicalizes the same path β which
issues an `lstat`. Those populate different cache slots (`followed` vs
`link`), so neither reuses the other. Every tsconfig in an
`extends`/`references` graph was therefore both `stat`'d **and**
`lstat`'d.
## Fix
Classify via the cached `link_metadata` (`lstat`, the same slot
canonicalization needs) and only fall back to `stat` when the path is
actually a symlink:
```rust
let cached_path = self.value(path);
let meta = match cached_path.link_metadata(&self.fs) {
Some(m) if m.is_symlink() => self.fs.metadata(path).ok(),
other => other,
};
```
The later `canonicalize(&self.value(&tsconfig_path))` now reuses that
cached `lstat` (same path β same `Arc<CachedPathImpl>` via the path
cache), removing one metadata syscall per config file on cold load.
Symlink-following classification is preserved for all four cases
(regular file/dir, symlinkβfile, symlinkβdir, missing).
This is a cold-only win (a tsconfig loads once per resolver), in the
same spirit as the earlier lstat/stat-unification work.
## Measurements
Traced over the tsconfig fixtures (cold load):
| scenario | before | after | Ξ |
| --- | --- | --- | --- |
| `extends-chain` (3 configs) | 21 syscalls | 18 | β14% |
| `project-references` (6 configs) | 39 syscalls | 33 | β15% |
The `stat` op is eliminated from tsconfig loading entirely.
## Verification
- `cargo test --all-features` β 315 tests pass (77 tsconfig)
- `cargo clippy --all-features` β clean
- `cargo check --all-features --all-targets` β clean Latest Branches
+7%
perf/dedup-is-dir-package-json +7%
release-plz-2026-06-18T23-48-37Z -6%
perf/tsconfig-cached-lstat Β© 2026 CodSpeed Technology