Session View Animation
Nucleic-Session: A8FFA1A6-443F-444A-A735-C53958D7E570 Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -258,4 +258,35 @@ struct MarkdownText: View {
|
||||
inlineCache.setObject(InlineBox(parsed), forKey: key)
|
||||
return parsed
|
||||
}
|
||||
|
||||
// MARK: - Pre-warming
|
||||
|
||||
/// Populate the block and inline caches for `markdown` ahead of layout. `AttributedString(markdown:)`
|
||||
/// is the dominant per-row cost when a long transcript first lays out, and the eager `VStack`
|
||||
/// runs it for every prose line synchronously — right as the session is pushed and the tab bar
|
||||
/// is sliding away, which is what makes the load-in jitter. Calling this off the main thread
|
||||
/// (see `TranscriptList`) does that parsing in the background so the first layout hits ready
|
||||
/// results instead.
|
||||
///
|
||||
/// Safe to call from any thread and redundantly: the caches are `NSCache` (thread-safe) and
|
||||
/// keyed only by the source string (independent of `bodySize`), so a warm value equals what
|
||||
/// the main thread would compute, and a repeat call is a cheap cache hit. Cooperatively
|
||||
/// cancellable — a huge transcript's warm loop bails the moment its owning task is cancelled.
|
||||
static func prewarm(_ markdown: String) {
|
||||
for block in parse(markdown) { // also warms the block cache
|
||||
if Task.isCancelled { return }
|
||||
switch block {
|
||||
case .code:
|
||||
break // a code block renders via `Text(code)` — no inline parse to warm
|
||||
case .text(let text):
|
||||
for raw in text.components(separatedBy: "\n") {
|
||||
if let content = classify(raw).inlineContent { _ = attributedInline(content) }
|
||||
}
|
||||
case .table(let rows):
|
||||
for row in rows where !Task.isCancelled {
|
||||
for cell in row { _ = attributedInline(cell) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user