Skip to content

Commit da5c839

Browse files
authored
fix(cli): debounce across edits to multiple files (#5701)
1 parent acb0084 commit da5c839

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

packages/cli/cli/versions.yml

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
- changelogEntry:
2+
- summary: |
3+
Improve performance of `fern docs dev` by debouncing across edits to multiple files,
4+
reducing unnecessary recomputation.
5+
type: fix
6+
irVersion: 55
7+
version: 0.50.16
8+
19
- changelogEntry:
210
- summary: |
311
This PR improves the performance of `fern docs dev`:

packages/cli/docs-preview/src/runPreviewServer.ts

+37-13
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ export async function runPreviewServer({
122122
let project = initialProject;
123123
let docsDefinition: DocsV1Read.DocsDefinition | undefined;
124124

125+
let reloadTimer: NodeJS.Timeout | null = null;
126+
let isReloading = false;
127+
const RELOAD_DEBOUNCE_MS = 1000;
128+
125129
const reloadDocsDefinition = async () => {
126130
context.logger.info("Reloading docs...");
127131
const startTime = Date.now();
@@ -161,25 +165,45 @@ export async function runPreviewServer({
161165
const watcher = new Watcher([absoluteFilePathToFern, ...additionalFilepaths], {
162166
recursive: true,
163167
ignoreInitial: true,
164-
debounce: 1000,
168+
debounce: 100,
165169
renameDetection: true
166170
});
171+
167172
// eslint-disable-next-line @typescript-eslint/no-misused-promises
168173
watcher.on("all", async (event: string, targetPath: string, _targetPathNext: string) => {
169174
context.logger.info(chalk.dim(`[${event}] ${targetPath}`));
170-
sendData({
171-
version: 1,
172-
type: "startReload"
173-
});
174-
// after the docsDefinition is reloaded, send a message to all connected clients to reload the page
175-
const reloadedDocsDefinition = await reloadDocsDefinition();
176-
if (reloadedDocsDefinition != null) {
177-
docsDefinition = reloadedDocsDefinition;
175+
176+
// Don't schedule another reload if one is in progress
177+
if (isReloading) {
178+
return;
178179
}
179-
sendData({
180-
version: 1,
181-
type: "finishReload"
182-
});
180+
181+
// Clear any existing timer
182+
if (reloadTimer != null) {
183+
clearTimeout(reloadTimer);
184+
}
185+
186+
// Set up new timer
187+
reloadTimer = setTimeout(() => {
188+
void (async () => {
189+
isReloading = true;
190+
sendData({
191+
version: 1,
192+
type: "startReload"
193+
});
194+
195+
const reloadedDocsDefinition = await reloadDocsDefinition();
196+
if (reloadedDocsDefinition != null) {
197+
docsDefinition = reloadedDocsDefinition;
198+
}
199+
200+
sendData({
201+
version: 1,
202+
type: "finishReload"
203+
});
204+
isReloading = false;
205+
})();
206+
}, RELOAD_DEBOUNCE_MS);
183207
});
184208

185209
// eslint-disable-next-line @typescript-eslint/no-misused-promises

0 commit comments

Comments
 (0)