notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 892d77d4e3f576bc9103398ba24f947d701fbb0d
parent 9ccbaf2db8721331b49c975118168a23e7b57d0f
Author: kernelkind <kernelkind@gmail.com>
Date:   Fri, 24 Oct 2025 10:43:31 -0400

chore(profiling): markup composite render path

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Mcrates/notedeck/src/imgcache.rs | 1+
Mcrates/notedeck/src/urls.rs | 9++++++++-
Mcrates/notedeck_columns/src/ui/timeline.rs | 33+++++++++++++++++++++++----------
Mcrates/notedeck_ui/src/profile/picture.rs | 3+++
4 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/crates/notedeck/src/imgcache.rs b/crates/notedeck/src/imgcache.rs @@ -545,6 +545,7 @@ pub struct LatestTexture { pub request_next_repaint: Option<SystemTime>, } +#[profiling::function] pub fn get_render_state<'a>( ctx: &egui::Context, images: &'a mut Images, diff --git a/crates/notedeck/src/urls.rs b/crates/notedeck/src/urls.rs @@ -231,6 +231,7 @@ pub struct SupportedMimeType { } impl SupportedMimeType { + #[profiling::function] pub fn from_extension(extension: &str) -> Result<Self, Error> { if let Some(mime) = mime_guess::from_ext(extension) .first() @@ -269,8 +270,13 @@ fn is_mime_supported(mime: &mime_guess::Mime) -> bool { mime.type_() == mime_guess::mime::IMAGE } +#[profiling::function] fn url_has_supported_mime(url: &str) -> MimeHostedAtUrl { - if let Ok(url) = Url::parse(url) { + let url = { + profiling::scope!("url parse"); + Url::parse(url) + }; + if let Ok(url) = url { if let Some(mut path) = url.path_segments() { if let Some(file_name) = path.next_back() { if let Some(ext) = std::path::Path::new(file_name) @@ -289,6 +295,7 @@ fn url_has_supported_mime(url: &str) -> MimeHostedAtUrl { MimeHostedAtUrl::Maybe } +#[profiling::function] pub fn supported_mime_hosted_at_url(urls: &mut UrlMimes, url: &str) -> Option<MediaCacheType> { match url_has_supported_mime(url) { MimeHostedAtUrl::Yes(cache_type) => Some(cache_type), diff --git a/crates/notedeck_columns/src/ui/timeline.rs b/crates/notedeck_columns/src/ui/timeline.rs @@ -705,16 +705,22 @@ fn render_reaction_cluster( underlying_note: &Note, reaction: &ReactionUnit, ) -> RenderEntryResponse { - let profiles_to_show: Vec<ProfileEntry> = reaction - .reactions - .values() - .filter(|r| !mute.is_pk_muted(r.sender.bytes())) - .map(|r| &r.sender) - .map(|p| ProfileEntry { - record: note_context.ndb.get_profile_by_pubkey(txn, p.bytes()).ok(), - pk: p, - }) - .collect(); + let profiles_to_show: Vec<ProfileEntry> = { + profiling::scope!("vec profile entries"); + reaction + .reactions + .values() + .filter(|r| !mute.is_pk_muted(r.sender.bytes())) + .map(|r| &r.sender) + .map(|p| { + profiling::scope!("ndb by pubkey"); + ProfileEntry { + record: note_context.ndb.get_profile_by_pubkey(txn, p.bytes()).ok(), + pk: p, + } + }) + .collect() + }; render_composite_entry( ui, @@ -728,6 +734,7 @@ fn render_reaction_cluster( } #[allow(clippy::too_many_arguments)] +#[profiling::function] fn render_composite_entry( ui: &mut egui::Ui, note_context: &mut NoteContext, @@ -772,6 +779,7 @@ fn render_composite_entry( .show(ui, |ui| { let show_label_newline = ui .horizontal_wrapped(|ui| { + profiling::scope!("header"); let pfps_resp = ui .allocate_ui_with_layout( vec2(ui.available_width(), 32.0), @@ -832,6 +840,7 @@ fn render_composite_entry( .inner; if let Some(desc) = show_label_newline { + profiling::scope!("description"); ui.add_space(4.0); ui.horizontal(|ui| { ui.add_space(48.0); @@ -868,6 +877,7 @@ fn render_composite_entry( RenderEntryResponse::Success(action) } +#[profiling::function] fn render_profiles( ui: &mut egui::Ui, profiles_to_show: Vec<ProfileEntry>, @@ -895,11 +905,14 @@ fn render_profiles( } let resp = ui.horizontal(|ui| { + profiling::scope!("scroll area"); ScrollArea::horizontal() .scroll_bar_visibility(ScrollBarVisibility::AlwaysHidden) .show(ui, |ui| { + profiling::scope!("scroll area closure"); let mut last_pfp_resp = None; for entry in profiles_to_show { + profiling::scope!("actual rendering individual pfp"); let mut resp = ui.add( &mut ProfilePic::from_profile_or_default(img_cache, entry.record.as_ref()) .size(24.0) diff --git a/crates/notedeck_ui/src/profile/picture.rs b/crates/notedeck_ui/src/profile/picture.rs @@ -144,9 +144,11 @@ fn render_pfp( match cur_state.texture_state { notedeck::TextureState::Pending => { + profiling::scope!("Render pending"); egui::InnerResponse::new(None, paint_circle(ui, ui_size, border, sense)) } notedeck::TextureState::Error(e) => { + profiling::scope!("Render error"); let r = paint_circle(ui, ui_size, border, sense); show_one_error_message(ui, &format!("Failed to fetch profile at url {url}: {e}")); egui::InnerResponse::new( @@ -159,6 +161,7 @@ fn render_pfp( ) } notedeck::TextureState::Loaded(textured_image) => { + profiling::scope!("Render loaded"); let texture_handle = ensure_latest_texture(ui, url, cur_state.gifs, textured_image, animation_mode);