Skip to content

Performance optimizations: formatter caching, view extraction, query limits#1763

Merged
garthvh merged 6 commits into
mainfrom
perf/easy-win-optimizations
May 9, 2026
Merged

Performance optimizations: formatter caching, view extraction, query limits#1763
garthvh merged 6 commits into
mainfrom
perf/easy-win-optimizations

Conversation

@garthvh
Copy link
Copy Markdown
Member

@garthvh garthvh commented May 9, 2026

What changed

Five performance optimizations from a codebase audit:

1. Static DateFormatter in CoTMessage (trivial)

ISO8601DateFormatter was instantiated on every toXML() call. Now a static let — reused across all instances.

2. CustomStringConvertible for DiscoveryScanState (trivial)

Removed String(describing:) reflection calls from log interpolations. Added CustomStringConvertible conformance with direct string returns.

3. Predicate-based favorite filter in CarPlay (easy)

fetchFavoriteContactItems() was loading ALL NodeInfoEntity records then filtering to favorites in memory. Moved the favorite == true filter into the #Predicate and added fetchLimit: 50.

4. Timer objectWillChange ordering in RateLimitedButton (easy)

objectWillChange.send() was called unconditionally at the top of each 1-second timer tick, even after all rate limits expired. Moved it after the cleanup check so the final tick doesn't trigger an unnecessary view redraw.

5. NodeDetail view body extraction (medium)

600+ line monolithic body property split into 6 @ViewBuilder section properties: nodeSection, environmentSection, powerSection, logsSection, actionsSection, administrationSection. Enables granular SwiftUI diffing — changes to one section no longer force recomputation of the entire hierarchy.

How it was tested

  • Built successfully for iOS

garthvh added 2 commits May 9, 2026 02:49
…limits

- CoTMessage: Make ISO8601DateFormatter a static let instead of creating
  per toXML() call
- DiscoveryScanEngine: Add CustomStringConvertible to DiscoveryScanState,
  remove String(describing:) wrapper from log interpolations
- CarPlaySceneDelegate: Move favorite filter into #Predicate and add
  fetchLimit: 50 to avoid loading all nodes
- RateLimitedButton: Move objectWillChange.send() after cleanup check
  to avoid unnecessary view redraws after timer stops
- NodeDetail: Extract 600-line body into 6 @ViewBuilder section
  properties for granular SwiftUI diffing
Remove Tips.MaxDisplayCount(3) from ConnectionTip. The tip uses
PersistentTipStyle which has no dismiss button, so it should always
appear when connected. The max count caused TipKit to internally
invalidate the tip after 3 views, rendering it invisible.
@garthvh garthvh requested a review from Copilot May 9, 2026 17:07
@garthvh garthvh self-assigned this May 9, 2026
@meshtastic meshtastic deleted a comment from github-actions Bot May 9, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR applies several targeted performance optimizations across TAK XML generation, discovery logging, CarPlay SwiftData fetching, and the Node Detail SwiftUI view composition.

Changes:

  • Reduced repeated work by caching/avoiding expensive formatting & reflection (CoTMessage date formatter caching; DiscoveryScanState CustomStringConvertible for logging).
  • Improved data/UI efficiency by moving filtering into SwiftData predicates and extracting NodeDetail’s large body into section subviews.
  • Minor behavioral/refresh adjustments (rate-limit timer objectWillChange ordering; TipKit options changed for ConnectionTip).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
Meshtastic/Views/Nodes/Helpers/NodeDetail.swift Extracts the large Node Detail body into section subviews; keeps feature parity while aiming to reduce SwiftUI recomputation.
Meshtastic/Views/Helpers/RateLimitedButton.swift Reorders timer tick publishing logic intended to reduce unnecessary UI updates.
Meshtastic/Tips/BluetoothTips.swift Changes ConnectionTip display options (removes max display count).
Meshtastic/Services/DiscoveryScanEngine.swift Adds CustomStringConvertible to DiscoveryScanState and uses it in log messages to avoid reflection.
Meshtastic/Helpers/TAK/CoTMessage.swift Caches an ISO8601DateFormatter for toXML() generation to reduce per-call allocation.
Meshtastic/CarPlay/CarPlaySceneDelegate.swift Moves favorites filtering into a SwiftData predicate and adds a fetch limit for performance.

Comment thread Meshtastic/Helpers/TAK/CoTMessage.swift Outdated
Comment thread Meshtastic/Views/Helpers/RateLimitedButton.swift
Comment thread Meshtastic/Tips/BluetoothTips.swift
Comment thread Meshtastic/Views/Nodes/Helpers/NodeDetail.swift
Comment thread Meshtastic/Views/Nodes/Helpers/NodeDetail.swift
Comment thread Meshtastic/Views/Nodes/Helpers/NodeDetail.swift
Comment thread Meshtastic/Views/Nodes/Helpers/NodeDetail.swift Outdated
Comment thread Meshtastic/Views/Nodes/Helpers/NodeDetail.swift
garthvh and others added 2 commits May 9, 2026 10:14
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread Meshtastic/Helpers/TAK/CoTMessage.swift
Comment thread Meshtastic/Views/Helpers/RateLimitedButton.swift
Comment thread Meshtastic/Tips/BluetoothTips.swift
@garthvh garthvh merged commit a24d834 into main May 9, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants