admin管理员组文章数量:1401247
I'm rendering a file in my SwiftUI MacOS app, using an AttributedString
for syntax highlighting (the AttributedString
is computed outside of the rendering loop). As soon as the file is a bit long (20KB in my case) the Text
view hangs for around 1s. Even displaying just a String
takes 0.1s which is really bad given the simple task. What are my options to address this performance issue? I noticed that giving a fixed frame size to the Text
view helps a bit (-30%) (I could do that as I'm using a fix sized font).
Would falling back to UIKit give me better performance?
import HighlightSwift
import Observation
import SwiftUI
// MARK: - Highlighter
@Observable
final class Highlighter {
init(_ content: String) {
self.content = content
Task {
attributedString = try await highlight.attributedText(content, language: .swift)
}
}
private(set) var attributedString: AttributedString?
private let content: String
private let highlight = Highlight()
}
// MARK: - ContentView
struct ContentView: View {
init() {
highlighter = Highlighter(fileContent)
}
var body: some View {
VStack {
HStack {
Button(action: {
isExpanded.toggle()
}, label: {
Text(isExpanded ? "Collapse" : "Expand")
})
Button(action: {
displayAttributedString.toggle()
}, label: {
Text(displayAttributedString ? "use String" : "use AttributedString")
})
}
if isExpanded {
if displayAttributedString {
// ScrollView {
InstrumentedView {
Text(highlighter.attributedString ?? "")
.font(.system(size: 12, weight: .regular, design: .monospaced))
}
// }
} else {
// ScrollView {
InstrumentedView {
Text(content)
.font(.system(size: 12, weight: .regular, design: .monospaced))
}
// }
}
}
Spacer(minLength: 0)
}
.padding()
}
var content: String {
fileContent
}
@State private var displayAttributedString = false
@State private var isExpanded = false
@Bindable private var highlighter: Highlighter
}
// MARK: - InstrumentedView
struct InstrumentedView<Content: View>: View {
init(build: @escaping () -> Content) {
self.build = build
print("init")
}
let build: () -> Content
var body: some View {
VStack {
if let renderingTime {
Text("Displayed in: \(renderingTime)s")
}
build()
}.onAppear {
print("appeared")
renderingTime = Date().timeIntervalSince(creationDate)
}
}
@State private var renderingTime: TimeInterval?
private let creationDate = Date()
}
本文标签: swiftRendering a long string in a Text View takes foreverStack Overflow
版权声明:本文标题:swift - Rendering a long string in a Text View takes forever - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744270904a2598178.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论