fix performance: cache subBlocks and syntax highlighting
- Cache parseSubBlocks per block (only reparse when content changes) - Cache highlightedHtml results (code+language key) - Prevents expensive KSyntaxHighlighting and regex on every render - Also fixes scroll loop with _scrolling guard
This commit is contained in:
parent
a6a1a227c3
commit
6f351b77e4
|
|
@ -54,7 +54,11 @@ QVariant ChatBlockModel::data(const QModelIndex &index, int role) const
|
|||
case ContentRole:
|
||||
return block.content;
|
||||
case SubBlocksRole:
|
||||
return parseSubBlocks(block.content);
|
||||
if (block.cachedContent != block.content) {
|
||||
block.cachedSubBlocks = parseSubBlocks(block.content);
|
||||
block.cachedContent = block.content;
|
||||
}
|
||||
return block.cachedSubBlocks;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
|
@ -251,6 +255,12 @@ QVariantList ChatBlockModel::parseSubBlocks(const QString &content) const
|
|||
|
||||
QString ChatBlockModel::highlightedHtml(const QString &code, const QString &language) const
|
||||
{
|
||||
// Check cache first
|
||||
QString cacheKey = language + "\x1f" + code;
|
||||
auto cached = m_highlightCache.find(cacheKey);
|
||||
if (cached != m_highlightCache.end())
|
||||
return *cached;
|
||||
|
||||
auto def = repo().definitionForName(language);
|
||||
if (!def.isValid()) {
|
||||
// Try by file extension
|
||||
|
|
@ -258,7 +268,9 @@ QString ChatBlockModel::highlightedHtml(const QString &code, const QString &lang
|
|||
}
|
||||
if (!def.isValid()) {
|
||||
// Return escaped plain text
|
||||
return code.toHtmlEscaped().replace('\n', "<br>");
|
||||
QString plain = code.toHtmlEscaped().replace('\n', "<br>");
|
||||
m_highlightCache.insert(cacheKey, plain);
|
||||
return plain;
|
||||
}
|
||||
|
||||
// Determine theme based on current palette
|
||||
|
|
@ -298,6 +310,7 @@ QString ChatBlockModel::highlightedHtml(const QString &code, const QString &lang
|
|||
html += "<br>";
|
||||
}
|
||||
|
||||
m_highlightCache.insert(cacheKey, html);
|
||||
return html;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ struct ChatBlock {
|
|||
Type type;
|
||||
QString name; // tool/call name, empty for others
|
||||
QString content; // raw text content
|
||||
mutable QVariantList cachedSubBlocks; // cached parseSubBlocks result
|
||||
mutable QString cachedContent; // content when subBlocks were cached
|
||||
};
|
||||
|
||||
// A sub-block within a markdown block (prose, code fence, diff)
|
||||
|
|
@ -70,6 +72,7 @@ private:
|
|||
|
||||
QString m_rawText;
|
||||
QList<ChatBlock> m_blocks;
|
||||
mutable QHash<QString, QString> m_highlightCache; // key: code+lang, value: html
|
||||
};
|
||||
|
||||
#endif // CHAT_BLOCK_MODEL_H
|
||||
|
|
|
|||
Reference in New Issue