mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-24 06:34:09 +00:00
fix: optimize serve/sourcemap startup from >180s to ~8s
Root cause: notify-debouncer-full with macos_kqueue caused 25K+ directory watch registrations to take >170s on large projects. Changes: - Replace notify-debouncer-full with notify-debouncer-mini to avoid FSEvents Create+Remove event cancellation and heavy per-watch overhead - Remove macos_kqueue feature; use FSEvents (matches upstream Rojo) - Fix VFS read guard: watch_enabled && watch_recursive -> watch_enabled so recording mechanism works when watch_recursive is false - Build RefPathIndex from patch_apply data instead of redundant 4.8s WalkDir + 5,854 file re-reads (populate_from_dir) - Use ServeSession::new_oneshot() for sourcemap without --watch - Restore simple synchronous watch setup (implicit during reads) Serve: >180s (never completed) -> ~8s to Listening Sourcemap: 14.3s -> ~9s All 489 tests passing.
This commit is contained in:
parent
4ddc4a3e31
commit
9cf4cea936
10 changed files with 236 additions and 210 deletions
|
|
@ -79,7 +79,17 @@ impl SourcemapCommand {
|
|||
let vfs = Vfs::new_default();
|
||||
vfs.set_watch_enabled(self.watch);
|
||||
|
||||
let session = ServeSession::new(vfs, project_path, None)?;
|
||||
let session_start = std::time::Instant::now();
|
||||
let session = if self.watch {
|
||||
ServeSession::new(vfs, project_path, None)?
|
||||
} else {
|
||||
ServeSession::new_oneshot(vfs, project_path)?
|
||||
};
|
||||
log::debug!(
|
||||
"[PERF] ServeSession::new() total: {:.1?}",
|
||||
session_start.elapsed()
|
||||
);
|
||||
|
||||
let mut cursor = session.message_queue().cursor();
|
||||
|
||||
let filter = if self.include_non_scripts {
|
||||
|
|
@ -93,6 +103,7 @@ impl SourcemapCommand {
|
|||
.build_global()
|
||||
.ok();
|
||||
|
||||
let sm_start = std::time::Instant::now();
|
||||
write_sourcemap(
|
||||
&session,
|
||||
self.output.as_deref(),
|
||||
|
|
@ -100,6 +111,7 @@ impl SourcemapCommand {
|
|||
self.absolute,
|
||||
false,
|
||||
)?;
|
||||
log::debug!("[PERF] write_sourcemap: {:.1?}", sm_start.elapsed());
|
||||
|
||||
if self.watch {
|
||||
if !std::io::stdin().is_terminal() {
|
||||
|
|
@ -259,6 +271,7 @@ pub(crate) fn write_sourcemap(
|
|||
use_absolute_paths: bool,
|
||||
quiet: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
let t0 = std::time::Instant::now();
|
||||
let tree = session.tree();
|
||||
|
||||
let canonical_project_dir = session.root_dir().to_path_buf();
|
||||
|
|
@ -270,22 +283,32 @@ pub(crate) fn write_sourcemap(
|
|||
filter,
|
||||
use_absolute_paths,
|
||||
);
|
||||
let t1 = std::time::Instant::now();
|
||||
|
||||
if let Some(output_path) = output {
|
||||
// Use standard JSON (not JSON5) for sourcemaps - required by external tools like LSPs
|
||||
let json_output = serde_json::to_string(&root_node)?;
|
||||
let t2 = std::time::Instant::now();
|
||||
|
||||
// Use atomic write (temp file + rename) to prevent file watchers from
|
||||
// reading partial files. Rename is atomic on all major filesystems when
|
||||
// source and destination are on the same filesystem.
|
||||
write_atomic(output_path, json_output.as_bytes())?;
|
||||
let t3 = std::time::Instant::now();
|
||||
|
||||
log::debug!(
|
||||
"[PERF] write_sourcemap: tree_walk={:.1?}, json_serialize={:.1?} ({} bytes), write={:.1?}",
|
||||
t1 - t0,
|
||||
t2 - t1,
|
||||
json_output.len(),
|
||||
t3 - t2,
|
||||
);
|
||||
|
||||
if !quiet {
|
||||
println!("Created sourcemap at {}", output_path.display());
|
||||
}
|
||||
} else {
|
||||
// Use standard JSON (not JSON5) for sourcemaps - required by external tools like LSPs
|
||||
let output = serde_json::to_string(&root_node)?;
|
||||
log::debug!(
|
||||
"[PERF] write_sourcemap: tree_walk={:.1?}, json_serialize=inline",
|
||||
t1 - t0
|
||||
);
|
||||
println!("{}", output);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue