Skip to content

Commit 3150991

Browse files
authored
(perf) Optimize fallback watcher (#955)
* ignore initial in fallback watcher * debounce fallback watcher event * simplify
1 parent 94f4124 commit 3150991

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

packages/language-server/src/lib/FallbackWatcher.ts

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import { FSWatcher, watch } from 'chokidar';
2+
import { debounce } from 'lodash';
23
import { join } from 'path';
34
import { DidChangeWatchedFilesParams, FileChangeType, FileEvent } from 'vscode-languageserver';
45
import { pathToUrl } from '../utils';
56

67
type DidChangeHandler = (para: DidChangeWatchedFilesParams) => void;
78

9+
const DELAY = 50;
10+
811
export class FallbackWatcher {
912
private readonly watcher: FSWatcher;
1013
private readonly callbacks: DidChangeHandler[] = [];
1114

15+
private undeliveredFileEvents: FileEvent[] = [];
16+
1217
constructor(glob: string, workspacePaths: string[]) {
1318
const gitOrNodeModules = /\.git|node_modules/;
1419
this.watcher = watch(
@@ -18,31 +23,43 @@ export class FallbackWatcher {
1823
gitOrNodeModules.test(path) &&
1924
// Handle Sapper's alias mapping
2025
!path.includes('src/node_modules') &&
21-
!path.includes('src\\node_modules')
26+
!path.includes('src\\node_modules'),
27+
28+
// typescript would scan the project files on init.
29+
// We only need to know what got updated.
30+
ignoreInitial: true,
31+
ignorePermissionErrors: true
2232
}
2333
);
2434

2535
this.watcher
26-
.on('add', (path) => this.callback(path, FileChangeType.Created))
27-
.on('unlink', (path) => this.callback(path, FileChangeType.Deleted))
28-
.on('change', (path) => this.callback(path, FileChangeType.Changed));
36+
.on('add', (path) => this.onFSEvent(path, FileChangeType.Created))
37+
.on('unlink', (path) => this.onFSEvent(path, FileChangeType.Deleted))
38+
.on('change', (path) => this.onFSEvent(path, FileChangeType.Changed));
2939
}
3040

31-
private convert(path: string, type: FileChangeType): DidChangeWatchedFilesParams {
32-
const event: FileEvent = {
41+
private convert(path: string, type: FileChangeType): FileEvent {
42+
return {
3343
type,
3444
uri: pathToUrl(path)
3545
};
46+
}
3647

37-
return {
38-
changes: [event]
39-
};
48+
private onFSEvent(path: string, type: FileChangeType) {
49+
const fileEvent = this.convert(path, type);
50+
51+
this.undeliveredFileEvents.push(fileEvent);
52+
this.scheduleTrigger();
4053
}
4154

42-
private callback(path: string, type: FileChangeType) {
43-
const para = this.convert(path, type);
55+
private readonly scheduleTrigger = debounce(() => {
56+
const para: DidChangeWatchedFilesParams = {
57+
changes: this.undeliveredFileEvents
58+
};
59+
this.undeliveredFileEvents = [];
60+
4461
this.callbacks.forEach((callback) => callback(para));
45-
}
62+
}, DELAY);
4663

4764
onDidChangeWatchedFiles(callback: DidChangeHandler) {
4865
this.callbacks.push(callback);

0 commit comments

Comments
 (0)