Repository navigation
perf: keep what the TypeScript check found between runs - #383
Conversation
A one-shot build, CI run or restarted dev server type checked the whole program from nothing: nothing the last run found was kept, and `readBuilderProgram` was never called. A program that writes nothing (the default `readonly` mode) is now built with `incremental` and a `tsBuildInfoFile` in the check's cache, by the EmitAndSemantic builder, whose state `emitBuildInfo` writes after each check. A compiler's first program reads it back. Files are versioned by a hash of what they hold rather than by time and size, so a state written by another process, after a checkout, is told from the files as they are. A mode that writes is left as it was; `cache: false` keeps nothing. 301 files, one-shot: 4.7 s / 12.2 s CPU / 560 MB -> 2.0 s / 6.0 s CPU / 460 MB on the second run. Watch rebuilds unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01App18sYbe6Vf6HDCjCXbvf
One or more co-authors of this pull request were not found. You must specify co-authors in commit message trailer via: Supported
Alternatively, if the co-author should not be included, remove the Please update your commit message(s) by doing |
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 16 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
EasyCLA fails here for the same reason as on #366–#375: the commit's Generated by Claude Code |
|
One CI job failed:
The likely cause is a late watcher event on Windows: a rebuild picks up the fixture's Separately, EasyCLA fails because the commits carry a Generated by Claude Code |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01App18sYbe6Vf6HDCjCXbvf
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #383 +/- ##
========================================
Coverage 99.64% 99.64%
========================================
Files 19 19
Lines 5570 5689 +119
========================================
+ Hits 5550 5669 +119
Misses 20 20 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Part of the performance series (#376–#382).
Problem
In watch mode the TypeScript check keeps its builder program warm. But every new process starts from nothing: a one-shot build, a CI run, a restarted dev server. In the default
readonlymode the check never wrote any state, and no mode ever read a.tsbuildinfoback, so each run type-checked the whole program again.The survey for this series found rollup's TypeScript plugins and
tsc --incrementalavoiding exactly this, withreadBuilderProgramandemitBuildInfo.Change
Applies when the program writes nothing (
readonly, the default) andcacheisn'tfalse:.tsbuildinfounder the check'scacheLocation. The new default isnode_modules/.cache/diagnostics-webpack-plugin/typescript/, with one file per config file and set of compiler options. AcacheLocationending in.tsbuildinfois used as the file itself.incrementaland thattsBuildInfoFile, using the EmitAndSemantic builder (only it hasemitBuildInfo). The state is written after each check.ts.readBuilderProgram. If it's unreadable or from another TypeScript version, the check starts from nothing.mtime:size, so a state written by another process still matches after a checkout or a CI cache restore. The stat-based reuse of parsed files in watch mode is unchanged.incremental, and so doesbuild.Measured
301 files, TypeScript check (no
skipLibCheck), two runs each:main(every run)main: first build / rebuild 1webpack alone takes about 1.6 s on this project, so on a later run the check adds about 0.4 s. Watch rebuilds after the first are unchanged.
Tests
test/typescript/state.test.js:cache: falsewrites nothing and reads nothing.cacheLocation, as the ESLint tests already do. The recorder mock records the EmitAndSemantic builder too.eslint,tsc, prettier, cspell andlint:schemaare clean.cacheLocation) and a minor changeset are updated, and types regenerated.Generated by Claude Code