Skip to content

metro-file-map: Remove FallbackWatcher's 1s startup delay on Windows - #2106

Draft
robhogan wants to merge 1 commit into
pr2105from
pr2106
Draft

robhogan wants to merge 1 commit into
pr2105from
pr2106

Conversation

@robhogan

@robhogan robhogan commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

On Windows, FallbackWatcher waits a second after setting up its watches:

if (platform === 'win32') {
// Inherited from sane: win32 needs a settling period after the watches
// are registered before events can be relied on.
await new Promise(resolve => setTimeout(resolve, 1000));
}

That's a holdover from sane. libuv issues ReadDirectoryChangesW before uv_fs_event_start returns, so a watch is live as soon as fs.watch returns:

https://github.com/libuv/libuv/blob/840404ce8ba7cc0204be52389a6cfff9f2c90fb6/src/win/fs-event.c#L310-L326

Benchmark

This takes 52% off watch-mode startup on Windows (1,939ms -> 926ms), about the second you'd expect. Linux is unchanged.

main #2105 This PR vs main vs #2105
Linux: Watch-mode start, warm cache 1,896ms 964ms 969ms -48.9% (-49.4% to -48.5%) +0.5% (-0.1% to +1.0%)
Windows: Watch-mode start, warm cache 2,554ms 1,939ms 926ms -63.7% (-63.9% to -63.6%) -52.2% (-52.5% to -51.9%)
Linux: Watch-mode start, cold cache 1,882ms 972ms 967ms -48.6% (-49.2% to -47.8%) -0.5% (-1.0% to +1.1%)
Windows: Watch-mode start, cold cache 2,547ms 1,911ms 912ms -64.2% (-64.3% to -64.0%) -52.3% (-52.5% to -52.1%)

Changelog

 - **[Performance]**: metro-file-map: Remove a 1s delay from file watcher startup on Windows without Watchman

Test plan

New unit test that changes made as soon as startWatching resolves are reported. It runs on Linux and Windows, and is skipped on macOS, where fs.watch starts FSEvents asynchronously (but FallbackWatcher isn't used). Benchmark as in #2104.

@robhogan
robhogan added this pull request to stack #2109 October 25, 2026 15:22
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 25, 2026
On Windows, `FallbackWatcher` waits a second after setting up its watches:

https://github.com/react/metro/blob/56efab302200568c919ac1b3c28dacf8d84fc692/packages/metro-file-map/src/watchers/FallbackWatcher.js#L77-L82

That's a holdover from `sane`. libuv issues `ReadDirectoryChangesW` before `uv_fs_event_start` returns, so a watch is live as soon as `fs.watch` returns:

https://github.com/libuv/libuv/blob/840404ce8ba7cc0204be52389a6cfff9f2c90fb6/src/win/fs-event.c#L310-L326

## Benchmark

This takes 52% off watch-mode startup on Windows (1,939ms -> 926ms), about the second you'd expect. Linux is unchanged.

|  | `main` | #2105 | This PR | vs `main` | vs #2105 |
|---|---|---|---|---|---|
| Linux: Watch-mode start, warm cache | 1,896ms | 964ms | 969ms | -48.9% (-49.4% to -48.5%) | +0.5% (-0.1% to +1.0%) |
| Windows: Watch-mode start, warm cache | 2,554ms | 1,939ms | 926ms | -63.7% (-63.9% to -63.6%) | -52.2% (-52.5% to -51.9%) |
| Linux: Watch-mode start, cold cache | 1,882ms | 972ms | 967ms | -48.6% (-49.2% to -47.8%) | -0.5% (-1.0% to +1.1%) |
| Windows: Watch-mode start, cold cache | 2,547ms | 1,911ms | 912ms | -64.2% (-64.3% to -64.0%) | -52.3% (-52.5% to -52.1%) |

## Changelog

```
 - **[Performance]**: metro-file-map: Remove a 1s delay from file watcher startup on Windows without Watchman
```

## Test plan

New unit test that changes made as soon as `startWatching` resolves are reported. It runs on Linux and Windows, and is skipped on macOS, where `fs.watch` starts FSEvents asynchronously (but `FallbackWatcher` isn't used). Benchmark as in #2104.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant