feat: improve recent worlds loading performance (#5079)
* Improve recent worlds loading performance * Make recent worlds not cause a layout shift by loading them asynchronously * Fix formatting * fix formatting --------- Co-authored-by: Creeperkatze <178587183+Creeperkatze@users.noreply.github.com> Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com> Co-authored-by: Calum H. <contact@cal.engineer> Co-authored-by: Calum H. <calum@modrinth.com>
This commit is contained in:
@@ -79,7 +79,7 @@ watch([() => props.recentInstances, () => showWorlds.value], async () => {
|
||||
})
|
||||
})
|
||||
|
||||
populateJumpBackIn()
|
||||
await populateJumpBackIn()
|
||||
.catch(() => {
|
||||
console.error('Failed to populate jump back in')
|
||||
})
|
||||
|
||||
@@ -31,7 +31,6 @@ use std::path::{Path, PathBuf};
|
||||
use std::sync::LazyLock;
|
||||
use std::time::Instant;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::task::JoinSet;
|
||||
use tokio_util::compat::FuturesAsyncWriteCompatExt;
|
||||
use url::Url;
|
||||
|
||||
@@ -404,7 +403,6 @@ async fn get_server_worlds_in_profile(
|
||||
.await
|
||||
.ok();
|
||||
|
||||
let first_server_index = worlds.len();
|
||||
for (index, server) in servers.into_iter().enumerate() {
|
||||
if server.hidden {
|
||||
// TODO: Figure out whether we want to hide or show direct connect servers
|
||||
@@ -436,31 +434,6 @@ async fn get_server_worlds_in_profile(
|
||||
};
|
||||
worlds.push(world);
|
||||
}
|
||||
|
||||
if let Some(join_log) = join_log {
|
||||
let mut futures = JoinSet::new();
|
||||
for (index, world) in worlds.iter().enumerate().skip(first_server_index)
|
||||
{
|
||||
// We can't check for the profile already having a last_played, in case the user joined
|
||||
// the target address directly more recently. This is often the case when using
|
||||
// quick-play before 1.20.
|
||||
if let WorldDetails::Server { address, .. } = &world.details
|
||||
&& let Ok((host, port)) = parse_server_address(address)
|
||||
{
|
||||
let host = host.to_owned();
|
||||
futures.spawn(async move {
|
||||
resolve_server_address(&host, port)
|
||||
.await
|
||||
.ok()
|
||||
.map(|x| (index, x))
|
||||
});
|
||||
}
|
||||
}
|
||||
for (index, address) in futures.join_all().await.into_iter().flatten() {
|
||||
worlds[index].last_played = join_log.get(&address).copied();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ use crate::launcher::quick_play_version::{
|
||||
QuickPlayServerVersion, QuickPlayVersion,
|
||||
};
|
||||
use crate::profile::QuickPlayType;
|
||||
use crate::server_address::{ServerAddress, parse_server_address};
|
||||
use crate::state::server_join_log::JoinLogEntry;
|
||||
use crate::state::{
|
||||
Credentials, JavaVersion, ProcessMetadata, ProfileInstallStage,
|
||||
};
|
||||
@@ -639,6 +641,31 @@ pub async fn launch_minecraft(
|
||||
if let QuickPlayType::Server(address) = &mut quick_play_type
|
||||
&& quick_play_version.server >= QuickPlayServerVersion::BuiltinLegacy
|
||||
{
|
||||
// Record last-played for the original server address immediately so
|
||||
// recent-worlds can match without DNS/SRV resolution.
|
||||
let original = match address {
|
||||
ServerAddress::Unresolved(address) => parse_server_address(address)
|
||||
.ok()
|
||||
.map(|(h, p)| (h.to_owned(), p)),
|
||||
ServerAddress::Resolved {
|
||||
original_host,
|
||||
original_port,
|
||||
..
|
||||
} => Some((original_host.clone(), *original_port)),
|
||||
};
|
||||
if let Some((host, port)) = original
|
||||
&& let Err(e) = (JoinLogEntry {
|
||||
profile_path: profile.path.clone(),
|
||||
host,
|
||||
port,
|
||||
join_time: Utc::now(),
|
||||
})
|
||||
.upsert(&state.pool)
|
||||
.await
|
||||
{
|
||||
tracing::warn!("Failed to write server join log entry: {e}");
|
||||
}
|
||||
|
||||
address.resolve().await?;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user