From 35f028daf27bb40e86829e7b7cc19aa72a62c0a0 Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Mon, 9 Oct 2023 04:39:52 +0100 Subject: [PATCH] perf(lsp): optimize formatting minified files (#20829) --- cli/lsp/language_server.rs | 30 ++++++++++++++---------------- cli/lsp/text.rs | 12 ++++++++++++ 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index dc36c05409..08ebfcceef 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -1651,11 +1651,11 @@ impl Inner { } // spawn a blocking task to allow doing other work while this is occurring - let format_result = deno_core::unsync::spawn_blocking({ + let text_edits = deno_core::unsync::spawn_blocking({ let fmt_options = self.fmt_options.options.clone(); let document = document.clone(); move || { - match document.maybe_parsed_source() { + let format_result = match document.maybe_parsed_source() { Some(Ok(parsed_source)) => { format_parsed_source(&parsed_source, &fmt_options) } @@ -1672,26 +1672,24 @@ impl Inner { // it's not a js/ts file, so attempt to format its contents format_file(&file_path, &document.content(), &fmt_options) } + }; + match format_result { + Ok(Some(new_text)) => Some(text::get_edits( + &document.content(), + &new_text, + document.line_index().as_ref(), + )), + Ok(None) => Some(Vec::new()), + Err(err) => { + lsp_warn!("Format error: {:#}", err); + None + } } } }) .await .unwrap(); - let text_edits = match format_result { - Ok(Some(new_text)) => Some(text::get_edits( - &document.content(), - &new_text, - document.line_index().as_ref(), - )), - Ok(None) => Some(Vec::new()), - Err(err) => { - // TODO(lucacasonato): handle error properly - lsp_warn!("Format error: {:#}", err); - None - } - }; - self.performance.measure(mark); if let Some(text_edits) = text_edits { if text_edits.is_empty() { diff --git a/cli/lsp/text.rs b/cli/lsp/text.rs index 26df170cee..8013edd528 100644 --- a/cli/lsp/text.rs +++ b/cli/lsp/text.rs @@ -210,6 +210,18 @@ pub fn get_edits(a: &str, b: &str, line_index: &LineIndex) -> Vec { if a == b { return vec![]; } + // Heuristic to detect things like minified files. `diff()` is expensive. + if b.chars().filter(|c| *c == '\n').count() + > line_index.utf8_offsets.len() * 3 + { + return vec![TextEdit { + range: lsp::Range { + start: lsp::Position::new(0, 0), + end: line_index.position_utf16(TextSize::from(a.len() as u32)), + }, + new_text: b.to_string(), + }]; + } let chunks = diff(a, b); let mut text_edits = Vec::::new(); let mut iter = chunks.iter().peekable();