Skip to content

Commit c951ccd

Browse files
authored
(perf) cache fileExists resolutions and path (#1325)
This make getCompletions perform many times faster, the bigger the project the more it benefits from the file exist cache. Computing path only once also helps a little overall as it's called quite often and url to path conversion is rather expensive.
1 parent 455efcc commit c951ccd

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

packages/language-server/src/lib/documents/Document.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export class Document extends WritableDocument {
1717
configPromise: Promise<SvelteConfig | undefined>;
1818
config?: SvelteConfig;
1919
html!: HTMLDocument;
20+
/**
21+
* Compute and cache directly because of performance reasons
22+
* and it will be called anyway.
23+
*/
24+
private path = urlToPath(this.url);
2025

2126
constructor(public url: string, public content: string) {
2227
super();
@@ -77,7 +82,7 @@ export class Document extends WritableDocument {
7782
* Returns the file path if the url scheme is file
7883
*/
7984
getFilePath(): string | null {
80-
return urlToPath(this.url);
85+
return this.path;
8186
}
8287

8388
/**

packages/language-server/src/plugins/typescript/module-loader.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,14 @@ export function createSvelteModuleLoader(
9090
fileExists: svelteSys.fileExists,
9191
readFile: svelteSys.readFile,
9292
readDirectory: svelteSys.readDirectory,
93-
deleteFromModuleCache: (path: string) => moduleCache.delete(path),
94-
deleteUnresolvedResolutionsFromCache: (path: string) =>
95-
moduleCache.deleteUnresolvedResolutionsFromCache(path),
93+
deleteFromModuleCache: (path: string) => {
94+
svelteSys.deleteFromCache(path);
95+
moduleCache.delete(path);
96+
},
97+
deleteUnresolvedResolutionsFromCache: (path: string) => {
98+
svelteSys.deleteFromCache(path);
99+
moduleCache.deleteUnresolvedResolutionsFromCache(path);
100+
},
96101
resolveModuleNames
97102
};
98103

packages/language-server/src/plugins/typescript/svelte-sys.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ import { ensureRealSvelteFilePath, isVirtualSvelteFilePath, toRealSvelteFilePath
66
* This should only be accessed by TS svelte module resolution.
77
*/
88
export function createSvelteSys(getSnapshot: (fileName: string) => DocumentSnapshot) {
9-
const svelteSys: ts.System = {
9+
const fileExistsCache = new Map<string, boolean>();
10+
11+
const svelteSys: ts.System & { deleteFromCache: (path: string) => void } = {
1012
...ts.sys,
1113
fileExists(path: string) {
12-
return ts.sys.fileExists(ensureRealSvelteFilePath(path));
14+
path = ensureRealSvelteFilePath(path);
15+
const exists = fileExistsCache.get(path) ?? ts.sys.fileExists(path);
16+
fileExistsCache.set(path, exists);
17+
return exists;
1318
},
1419
readFile(path: string) {
1520
const snapshot = getSnapshot(path);
@@ -19,6 +24,13 @@ export function createSvelteSys(getSnapshot: (fileName: string) => DocumentSnaps
1924
const extensionsWithSvelte = (extensions ?? []).concat('.svelte');
2025

2126
return ts.sys.readDirectory(path, extensionsWithSvelte, exclude, include, depth);
27+
},
28+
deleteFile(path) {
29+
fileExistsCache.delete(ensureRealSvelteFilePath(path));
30+
return ts.sys.deleteFile?.(path);
31+
},
32+
deleteFromCache(path) {
33+
fileExistsCache.delete(ensureRealSvelteFilePath(path));
2234
}
2335
};
2436

0 commit comments

Comments
 (0)