perf: 优化实例启动性能并修复过渡动画对齐

依赖校验戳缓存(18.6s→0.1s)、并发化库/资产校验、启动计时埋点、过渡动画200ms、窗口客户区精确对齐、遮罩即时显示、debug构建写文件日志。
This commit is contained in:
Xiao-no-love
2026-09-16 13:10:37 +08:00
parent 776f621436
commit ccb921f4bd
7 changed files with 457 additions and 535 deletions

View File

@ -1525,8 +1525,11 @@ pub async fn launch_minecraft(
) -> crate::Result<ProcessMetadata> {
let instance = &context.instance;
let content_set = &context.applied_content_set;
let mut __lt = std::time::Instant::now();
let mut combined_java_args =
crate::pack::hosted::java_arguments(&instance.id).await?;
tracing::info!("[launch-timing] hosted_java_arguments: {}ms", __lt.elapsed().as_millis());
__lt = std::time::Instant::now();
combined_java_args.extend_from_slice(java_args);
let java_args = combined_java_args.as_slice();
@ -1832,6 +1835,8 @@ pub async fn launch_minecraft(
.await?;
}
}
tracing::info!("[launch-timing] resolve_version_info: {}ms", __lt.elapsed().as_millis());
__lt = std::time::Instant::now();
let java_version = if let Some(java) =
context.launch_overrides.java_path.as_ref()
@ -1886,6 +1891,8 @@ pub async fn launch_minecraft(
let java_version =
crate::api::jre::check_jre(java_version.path.clone().into()).await?;
validate_loader_java_version(&version_info, &java_version)?;
tracing::info!("[launch-timing] resolve_java: {}ms", __lt.elapsed().as_millis());
__lt = std::time::Instant::now();
// Runtime-verify and fall back for GC arguments against the *actual* JVM
// that will run Minecraft. The frontend supplies an ordered candidate
@ -1915,6 +1922,8 @@ pub async fn launch_minecraft(
}
*gc_report = Some(report);
}
tracing::info!("[launch-timing] resolve_gc: {}ms", __lt.elapsed().as_millis());
__lt = std::time::Instant::now();
// Apply the mappable linked-launcher private settings for directly
// associated instances on top of the resolved launch configuration.
@ -2020,6 +2029,8 @@ pub async fn launch_minecraft(
None => vanilla_client_path,
}
};
tracing::info!("[launch-timing] assemble_client: {}ms", __lt.elapsed().as_millis());
__lt = std::time::Instant::now();
let args = version_info.arguments.clone().unwrap_or_default();
let mut command = match wrapper {
@ -2065,6 +2076,7 @@ pub async fn launch_minecraft(
&& let (Some(direct), Some(libraries)) =
(&direct_launch, linked_libraries.as_deref())
{
let __t_ensure = std::time::Instant::now();
direct_ensure::ensure_direct_launch_dependencies(
&state,
direct,
@ -2074,6 +2086,7 @@ pub async fn launch_minecraft(
minecraft_updated,
)
.await?;
tracing::info!("[launch-timing] ensure_deps(libs+assets+log): {}ms", __t_ensure.elapsed().as_millis());
}
let natives_dir = if let Some(direct) = &direct_launch {
@ -2085,9 +2098,11 @@ pub async fn launch_minecraft(
};
// Linked native archives can change outside Axolotl, so rebuild only the
// Axolotl-owned linked cache on every launch. Never mutate linked folders.
let __t_rm = std::time::Instant::now();
if direct_launch.is_some() && natives_dir.exists() {
io::remove_dir_all(&natives_dir).await?;
}
tracing::info!("[launch-timing] remove_old_natives: {}ms", __t_rm.elapsed().as_millis());
if !natives_dir.exists() {
io::create_dir_all(&natives_dir).await?;
}
@ -2098,6 +2113,7 @@ pub async fn launch_minecraft(
// launch; the managed restore path below must never touch them.
let target = natives_dir.clone();
let java_arch = java_version.architecture.clone();
let __t_extract = std::time::Instant::now();
tokio::task::spawn_blocking(move || {
extract_linked_natives(
&direct,
@ -2108,6 +2124,7 @@ pub async fn launch_minecraft(
)
})
.await??;
tracing::info!("[launch-timing] extract_linked_natives: {}ms", __t_extract.elapsed().as_millis());
} else if direct_launch.is_none() {
if offline_mode {
natives::prepare_native_libraries(
@ -2137,6 +2154,8 @@ pub async fn launch_minecraft(
}
}
tracing::info!("[launch-timing] ensure_libraries_and_natives: {}ms", __lt.elapsed().as_millis());
__lt = std::time::Instant::now();
tracing::debug!(
"Found QuickPlayVersion for {}: {quick_play_version:?}",
content_set.game_version
@ -2399,7 +2418,7 @@ pub async fn launch_minecraft(
let logs_folder = state.directories.game_logs_dir(&instance_path);
// Create Minecraft child by inserting it into the state
// This also spawns the process and prepares the subsequent processes
state
let __launch_process = state
.process_manager
.insert_new_process(
&instance.id,
@ -2443,7 +2462,9 @@ pub async fn launch_minecraft(
Ok(())
},
)
.await
.await;
tracing::info!("[launch-timing] process_spawn: {}ms", __lt.elapsed().as_millis());
__launch_process
}
#[cfg(test)]