Optimize UI performance with message caching and List view

- Convert BitchatMessage from struct to class for efficient caching
- Cache formatted AttributedStrings to avoid expensive regex on every render
- Replace ScrollView+LazyVStack with native List for better cell reuse
- Implement message windowing (show last 100 messages for performance)
- Add LazyLinkPreviewView that defers loading for 0.5s to improve scroll performance

These optimizations significantly improve scroll performance, especially with large message lists.
This commit is contained in:
jack
2025-07-24 12:38:31 +02:00
parent a338008511
commit f45c52e9d3
3 changed files with 111 additions and 33 deletions
+35 -1
View File
@@ -929,7 +929,7 @@ enum DeliveryStatus: Codable, Equatable {
}
}
struct BitchatMessage: Codable, Equatable {
class BitchatMessage: Codable {
let id: String
let sender: String
let content: String
@@ -942,6 +942,23 @@ struct BitchatMessage: Codable, Equatable {
let mentions: [String]? // Array of mentioned nicknames
var deliveryStatus: DeliveryStatus? // Delivery tracking
// Cached formatted text (not included in Codable)
private var _cachedFormattedText: [String: AttributedString] = [:]
func getCachedFormattedText(isDark: Bool) -> AttributedString? {
return _cachedFormattedText["\(isDark)"]
}
func setCachedFormattedText(_ text: AttributedString, isDark: Bool) {
_cachedFormattedText["\(isDark)"] = text
}
// Codable implementation
enum CodingKeys: String, CodingKey {
case id, sender, content, timestamp, isRelay, originalSender
case isPrivate, recipientNickname, senderPeerID, mentions, deliveryStatus
}
init(id: String? = nil, sender: String, content: String, timestamp: Date, isRelay: Bool, originalSender: String? = nil, isPrivate: Bool = false, recipientNickname: String? = nil, senderPeerID: String? = nil, mentions: [String]? = nil, deliveryStatus: DeliveryStatus? = nil) {
self.id = id ?? UUID().uuidString
self.sender = sender
@@ -957,6 +974,23 @@ struct BitchatMessage: Codable, Equatable {
}
}
// Equatable conformance for BitchatMessage
extension BitchatMessage: Equatable {
static func == (lhs: BitchatMessage, rhs: BitchatMessage) -> Bool {
return lhs.id == rhs.id &&
lhs.sender == rhs.sender &&
lhs.content == rhs.content &&
lhs.timestamp == rhs.timestamp &&
lhs.isRelay == rhs.isRelay &&
lhs.originalSender == rhs.originalSender &&
lhs.isPrivate == rhs.isPrivate &&
lhs.recipientNickname == rhs.recipientNickname &&
lhs.senderPeerID == rhs.senderPeerID &&
lhs.mentions == rhs.mentions &&
lhs.deliveryStatus == rhs.deliveryStatus
}
}
protocol BitchatDelegate: AnyObject {
func didReceiveMessage(_ message: BitchatMessage)
func didConnectToPeer(_ peerID: String)