vitejs/vite

Improve `loadTsconfigJsonForFile` performance

Closed this issue · 3 comments

Clear and concise description of the problem

const loadedTsconfig = await loadTsconfigJsonForFile(filename)

loadTsconfigJsonForFile takes most of the time in transformWithEsbuild.

When I measured with my repository, loadTsconfigJsonForFile(filename) took 150571ms totally. On the other hand, transform(code, resolvedOptions) took 45505ms.

After studying, I found that this find function in tsconfck was the bottleneck.
Because my repository has many files in 4th to 5th depth from tsconfig.json, this function takes a lot of time to traverse.

Suggested solution

I have two ideas to solve this.

First one is to keep negative cache for find function like below. This will reduce calling fs.stat which is called inside tsconfigDir function.

const negativeCache = new Set()
export async function find(filename: string) {
	let dir = path.dirname(path.resolve(filename));
	while (dir) {
                if (!negativeCache.has(dir)) {
		    const tsconfig = await tsconfigInDir(dir);
		    if (tsconfig) {
			    return tsconfig;
		    }
		    negativeCache.add(dir);
                } else {
			const parent = path.dirname(dir);
			if (parent === dir) {
				break;
			} else {
				dir = parent;
			}
		}
	}
	throw new Error(`no tsconfig file found for ${filename}`);
}

Second one is to collect all tsconfig.json inside project folder before transpiling.

const tsconfigPaths = new Set(getTsconfigPaths())
export async function find(filename: string) {
	let dir = path.dirname(path.resolve(filename));
	while (dir) {
                if (tsconfigPaths.has(dir)) {
		    const tsconfig = await tsconfigInDir(dir);
		    if (tsconfig) {
			    return tsconfig;
		    }
                } else {
			const parent = path.dirname(dir);
			if (parent === dir) {
				break;
			} else {
				dir = parent;
			}
		}
	}
	throw new Error(`no tsconfig file found for ${filename}`);
}

Alternative

No response

Additional context

No response

Validations

bluwy commented

Should this be an issue for tsconfck? cc @dominikg

yes, this should be in tsconfck repo

Ok I will create it in tsconfck repository 👍