⚡ perf(vscode): 代码阅读预览发给页面的块带内容指纹:扩展端按卡片内容、在源码里占的地方连同子块的指纹算摘要,页面按指纹认出没变的块沿用原来的对象,不再逐块深比内容,5126 行的文档到了比对 10.6ms → 0.4ms

This commit is contained in:
cruldra committed 2026-10-13 16:39:59 +11:00
1 parent ad5f559e92
commit 266dc42bc5
13 files changed
+194 -26

No files matched your search

+13 -2
View File
@@ -2,6 +2,7 @@ import type { BlockView } from '../blockView'
import type { Inline, PreviewTable, PreviewText, PropertyItem, PropertyRow, Segment, SourceRange } from '../contract'
import type { BlockMarks, ItemDiff, ItemsDiff, RowDiff, RowsDiff, TextDiff } from '../diff/viewDiff'
import type { BlockSpan, PageBlock, PageCard } from './messages'
import { createHash } from 'node:crypto'
/**
* 扩展端的块(位置都是文件里的)→ 发给页面的块(见 PageBlock):块在源码里占的地方按相对的量记(BlockSpan),
@@ -101,9 +102,17 @@ export function pageCard(block: BlockView, base: number): PageCard {
/** 文件里的一处:行号、下标 */
interface Point { line: number, offset: number }
/** 一块的内容指纹:卡片的内容、span、各子块的指纹一起摘要,取前 16 个字符(96 位) */
function fingerprint(card: PageCard, span: BlockSpan, children: readonly PageBlock[]): string {
const hash = createHash('sha1').update(JSON.stringify(card)).update(JSON.stringify(span))
for (const child of children)
hash.update(child.hash)
return hash.digest('base64url').slice(0, 16)
}
/**
* 一串兄弟块发给页面的样子:每块的开头是它第一行的行首、结尾是最后一行的行尾,离前一块的结尾(第一块从 from 算)隔多远、自己多长记成 span,
* 子块从这块的开头算起。
* 子块从这块的开头算起;带上内容指纹(见 PageBlock.hash)。
*/
function pageList(blocks: readonly BlockView[], lines: SourceLines, from: Point): PageBlock[] {
let cursor = from
@@ -112,7 +121,9 @@ function pageList(blocks: readonly BlockView[], lines: SourceLines, from: Point)
const end = { line: block.endLine, offset: lines.end(block.endLine) }
const span: BlockSpan = { lineGap: start.line - cursor.line, gap: start.offset - cursor.offset, lines: end.line - start.line, length: end.offset - start.offset }
cursor = end
return { ...pageCard(block, start.offset), span, children: pageList(block.children, lines, start) }
const card = pageCard(block, start.offset)
const children = pageList(block.children, lines, start)
return { ...card, span, hash: fingerprint(card, span, children), children }
})
}