Skip to content

Commit

Permalink
(perf) cache fileExists resolutions and path (#1325)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dummdidumm authored Jan 9, 2022
1 parent 455efcc commit c951ccd
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
7 changes: 6 additions & 1 deletion packages/language-server/src/lib/documents/Document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export class Document extends WritableDocument {
configPromise: Promise<SvelteConfig | undefined>;
config?: SvelteConfig;
html!: HTMLDocument;
/**
* Compute and cache directly because of performance reasons
* and it will be called anyway.
*/
private path = urlToPath(this.url);

constructor(public url: string, public content: string) {
super();
Expand Down Expand Up @@ -77,7 +82,7 @@ export class Document extends WritableDocument {
* Returns the file path if the url scheme is file
*/
getFilePath(): string | null {
return urlToPath(this.url);
return this.path;
}

/**
Expand Down
11 changes: 8 additions & 3 deletions packages/language-server/src/plugins/typescript/module-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,14 @@ export function createSvelteModuleLoader(
fileExists: svelteSys.fileExists,
readFile: svelteSys.readFile,
readDirectory: svelteSys.readDirectory,
deleteFromModuleCache: (path: string) => moduleCache.delete(path),
deleteUnresolvedResolutionsFromCache: (path: string) =>
moduleCache.deleteUnresolvedResolutionsFromCache(path),
deleteFromModuleCache: (path: string) => {
svelteSys.deleteFromCache(path);
moduleCache.delete(path);
},
deleteUnresolvedResolutionsFromCache: (path: string) => {
svelteSys.deleteFromCache(path);
moduleCache.deleteUnresolvedResolutionsFromCache(path);
},
resolveModuleNames
};

Expand Down
16 changes: 14 additions & 2 deletions packages/language-server/src/plugins/typescript/svelte-sys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ import { ensureRealSvelteFilePath, isVirtualSvelteFilePath, toRealSvelteFilePath
* This should only be accessed by TS svelte module resolution.
*/
export function createSvelteSys(getSnapshot: (fileName: string) => DocumentSnapshot) {
const svelteSys: ts.System = {
const fileExistsCache = new Map<string, boolean>();

const svelteSys: ts.System & { deleteFromCache: (path: string) => void } = {
...ts.sys,
fileExists(path: string) {
return ts.sys.fileExists(ensureRealSvelteFilePath(path));
path = ensureRealSvelteFilePath(path);
const exists = fileExistsCache.get(path) ?? ts.sys.fileExists(path);
fileExistsCache.set(path, exists);
return exists;
},
readFile(path: string) {
const snapshot = getSnapshot(path);
Expand All @@ -19,6 +24,13 @@ export function createSvelteSys(getSnapshot: (fileName: string) => DocumentSnaps
const extensionsWithSvelte = (extensions ?? []).concat('.svelte');

return ts.sys.readDirectory(path, extensionsWithSvelte, exclude, include, depth);
},
deleteFile(path) {
fileExistsCache.delete(ensureRealSvelteFilePath(path));
return ts.sys.deleteFile?.(path);
},
deleteFromCache(path) {
fileExistsCache.delete(ensureRealSvelteFilePath(path));
}
};

Expand Down

0 comments on commit c951ccd

Please sign in to comment.