From 27f197ce947fed626f6d2b98431562443b5c64c3 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Fri, 18 Oct 2024 13:54:07 +0800 Subject: [PATCH] perf: cache SWC loader (#7965) * cache swc loader * fix ident * fix clippy --- .../src/plugins/js_loader/resolver.rs | 43 ++++++++++++++++--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/crates/rspack_binding_options/src/plugins/js_loader/resolver.rs b/crates/rspack_binding_options/src/plugins/js_loader/resolver.rs index e90670955a8..d08f37f1cea 100644 --- a/crates/rspack_binding_options/src/plugins/js_loader/resolver.rs +++ b/crates/rspack_binding_options/src/plugins/js_loader/resolver.rs @@ -1,4 +1,7 @@ -use std::sync::Arc; +use std::{ + borrow::Cow, + sync::{Arc, LazyLock}, +}; use rspack_collections::{Identifiable, Identifier}; use rspack_core::{ @@ -14,8 +17,10 @@ use rspack_hook::plugin_hook; use rspack_loader_lightningcss::{config::Config, LIGHTNINGCSS_LOADER_IDENTIFIER}; use rspack_loader_preact_refresh::PREACT_REFRESH_LOADER_IDENTIFIER; use rspack_loader_react_refresh::REACT_REFRESH_LOADER_IDENTIFIER; -use rspack_loader_swc::SWC_LOADER_IDENTIFIER; +use rspack_loader_swc::{SwcLoader, SWC_LOADER_IDENTIFIER}; use rspack_paths::Utf8Path; +use rustc_hash::FxHashMap; +use tokio::sync::RwLock; use super::{JsLoaderRspackPlugin, JsLoaderRspackPluginInner}; @@ -39,15 +44,37 @@ pub fn serde_error_to_miette( let span = LabeledSpan::at_offset(offset.offset(), e.to_string()); miette!(labels = vec![span], "{msg}").with_source_code(content.clone()) } -pub fn get_builtin_loader(builtin: &str, options: Option<&str>) -> Result { + +type SwcLoaderCache<'a> = LazyLock, Arc), Arc>>>; +static SWC_LOADER_CACHE: SwcLoaderCache = LazyLock::new(|| RwLock::new(FxHashMap::default())); + +pub async fn get_builtin_loader(builtin: &str, options: Option<&str>) -> Result { let options: Arc = options.unwrap_or("{}").into(); if builtin.starts_with(SWC_LOADER_IDENTIFIER) { - return Ok(Arc::new( + if let Some(loader) = SWC_LOADER_CACHE + .read() + .await + .get(&(Cow::Borrowed(builtin), options.clone())) + { + return Ok(loader.clone()); + } + + let loader = Arc::new( rspack_loader_swc::SwcLoader::new(serde_json::from_str(options.as_ref()).map_err(|e| { - serde_error_to_miette(e, options, "failed to parse builtin:swc-loader options") + serde_error_to_miette( + e, + options.clone(), + "failed to parse builtin:swc-loader options", + ) })?) .with_identifier(builtin.into()), - )); + ); + + SWC_LOADER_CACHE.write().await.insert( + (Cow::Owned(builtin.to_owned()), options.clone()), + loader.clone(), + ); + return Ok(loader); } if builtin.starts_with(LIGHTNINGCSS_LOADER_IDENTIFIER) { @@ -115,7 +142,9 @@ pub(crate) async fn resolve_loader( // FIXME: not belong to napi if loader_request.starts_with(BUILTIN_LOADER_PREFIX) { - return get_builtin_loader(loader_request, loader_options).map(Some); + return get_builtin_loader(loader_request, loader_options) + .await + .map(Some); } let resolve_result = resolver