diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 7f6c5dbe8a7..c493cf8f87f 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -159,6 +159,11 @@ namespace ts { let timerHandleForRecompilation: number; // Handle for 0.25s wait timer to trigger recompilation let timerHandleForDirectoryChanges: number; // Handle for 0.25s wait timer to trigger directory change handler + // This map stores and reuses results of fileExists check that happen inside 'createProgram' + // This allows to save time in module resolution heavy scenarios when existence of the same file might be checked multiple times. + let cachedExistingFiles: Map; + let hostFileExists: typeof compilerHost.fileExists; + if (commandLine.options.locale) { if (!isJSONSupported()) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale")); @@ -274,8 +279,14 @@ namespace ts { compilerHost = createCompilerHost(compilerOptions); hostGetSourceFile = compilerHost.getSourceFile; compilerHost.getSourceFile = getSourceFile; + + hostFileExists = compilerHost.fileExists; + compilerHost.fileExists = cachedFileExists; } + // reset the cache of existing files + cachedExistingFiles = {}; + let compileResult = compile(rootFileNames, compilerOptions, compilerHost); if (!compilerOptions.watch) { @@ -286,6 +297,13 @@ namespace ts { reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes)); } + function cachedFileExists(fileName: string): boolean { + if (hasProperty(cachedExistingFiles, fileName)) { + return cachedExistingFiles[fileName]; + } + return cachedExistingFiles[fileName] = hostFileExists(fileName); + } + function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) { // Return existing SourceFile object if one is available if (cachedProgram) {