Defer sticker reads via crl::on_main chain for faster first paint

Instead of reading all sticker sets synchronously in crl::on_main,
chain each read step via crl::on_main so that paint events can be
processed between heavy file reads. This moves first paint from
~2807ms to ~1294ms by allowing the UI to render before sticker
loading completes.
This commit is contained in:
futpib
2026-02-18 02:08:06 +00:00
committed by John Preston
parent 8eab8af02d
commit ffea1e3917
+50 -16
View File
@@ -181,6 +181,55 @@ Session::Session(
_selfUserpicView = view.cloud;
}, lifetime());
// Storage::Account uses Main::Account::session() in those methods.
// So they can't be called during Main::Session construction.
// They are deferred via crl::on_main which fires after the
// constructor returns and _session is set.
//
// Steps are chained via crl::on_main so that paint events
// can be processed between heavy file reads.
const auto steps = std::make_shared<std::vector<Fn<void()>>>(
std::initializer_list<Fn<void()>>{
[=] {
local().readInstalledStickers();
}, [=] {
local().readInstalledMasks();
}, [=] {
local().readInstalledCustomEmoji();
}, [=] {
data().stickers().notifyUpdated(Data::StickersType::Stickers);
data().stickers().notifyUpdated(Data::StickersType::Masks);
data().stickers().notifyUpdated(Data::StickersType::Emoji);
}, [=] {
local().readFeaturedStickers();
}, [=] {
local().readFeaturedCustomEmoji();
}, [=] {
local().readRecentStickers();
local().readRecentMasks();
local().readFavedStickers();
local().readSavedGifs();
}, [=] {
data().stickers().notifyUpdated(Data::StickersType::Stickers);
data().stickers().notifyUpdated(Data::StickersType::Masks);
data().stickers().notifyUpdated(Data::StickersType::Emoji);
data().stickers().notifySavedGifsUpdated();
DEBUG_LOG(("Init: Account stored data load finished."));
},
});
const auto runNext = std::make_shared<Fn<void()>>();
*runNext = crl::guard(this, [=] {
if (steps->empty()) {
return;
}
auto step = std::move(steps->front());
steps->erase(steps->begin());
step();
if (!steps->empty()) {
crl::on_main(*runNext);
}
});
crl::on_main(this, [=] {
using Flag = Data::PeerUpdate::Flag;
changes().peerUpdates(
@@ -211,22 +260,7 @@ Session::Session(
saveSettingsDelayed();
}
// Storage::Account uses Main::Account::session() in those methods.
// So they can't be called during Main::Session construction.
local().readInstalledStickers();
local().readInstalledMasks();
local().readInstalledCustomEmoji();
local().readFeaturedStickers();
local().readFeaturedCustomEmoji();
local().readRecentStickers();
local().readRecentMasks();
local().readFavedStickers();
local().readSavedGifs();
data().stickers().notifyUpdated(Data::StickersType::Stickers);
data().stickers().notifyUpdated(Data::StickersType::Masks);
data().stickers().notifyUpdated(Data::StickersType::Emoji);
data().stickers().notifySavedGifsUpdated();
DEBUG_LOG(("Init: Account stored data load finished."));
crl::on_main(*runNext);
});
#ifndef TDESKTOP_DISABLE_SPELLCHECK