⚡ perf(vscode): 代码阅读预览发给页面的块只记相对位置:块在源码里占的地方记成离前一块多远、自己多长,块里名字的下标从块的开头算,页面从文件开头累加回文件里的位置、和扩展端打交道的地方都在一处换算;靠前改了代码,后面内容没变的块发过去一模一样,扩展端自己的块和发给页面的块分成两种类型

This commit is contained in:
cruldra committed 2026-10-13 16:32:18 +11:00
1 parent 3a2815c19c
commit ad5f559e92
43 files changed
+980 -424

No files matched your search

@@ -1,5 +1,6 @@
// @vitest-environment happy-dom
import type { Placement } from './placement'
import type { BlockBox } from './scrollPosition'
import { afterEach, describe, expect, it } from 'vitest'
import { PageLayout } from './pageLayout'
@@ -31,8 +32,13 @@ function level(owner: string | undefined, ...children: HTMLElement[]): HTMLEleme
return div('cr-level', owner === undefined ? {} : { 'data-owner': owner }, div('guide'), div('column', {}, ...children))
}
/** 各块在文件里的起始行(页面上不记行号,按块 id 从文档里各块的位置取) */
const LINES: Record<string, number> = {}
const PLACEMENT: Placement = { of: id => id in LINES ? { offset: 0, line: LINES[id], endLine: LINES[id] } : undefined }
function card(id: string, line: number, top: number, bottom: number, editing = false): HTMLElement {
return place(div('cr-block', { 'data-id': id, 'data-line': String(line), ...(editing && { 'data-editing': '' }) }), top, bottom)
LINES[id] = line
return place(div('cr-block', { 'data-id': id, ...(editing && { 'data-editing': '' }) }), top, bottom)
}
/**
@@ -42,9 +48,9 @@ function page(): { root: HTMLElement, cards: BlockBox[] } {
const root = document.createElement('div')
root.append(level(
undefined,
place(div('cr-item', { 'data-line': '0' }, card('0', 0, 0, 100), place(level('0', card('0.0', 2, 120, 300), card('0.1', 8, 320, 500)), 110, 900)), 0, 1000),
place(div('cr-item', { 'data-line': '20' }, card('1', 20, 1010, 1500, true)), 1010, 1500),
place(div('cr-item', { 'data-line': '40' }, card('2', 40, 1510, 2000)), 1510, 2000),
place(div('cr-item', {}, card('0', 0, 0, 100), place(level('0', card('0.0', 2, 120, 300), card('0.1', 8, 320, 500)), 110, 900)), 0, 1000),
place(div('cr-item', {}, card('1', 20, 1010, 1500, true)), 1010, 1500),
place(div('cr-item', {}, card('2', 40, 1510, 2000)), 1510, 2000),
))
document.body.append(root)
const cards = [[0, 0, 100], [2, 120, 300], [8, 320, 500], [20, 1010, 1500], [40, 1510, 2000]].map(([line, top, bottom]) => ({ line, top, bottom }))
@@ -60,7 +66,7 @@ describe('卡片位置量过就记着', () => {
it('滚动位置、包含某一行的块:和把全部卡片量一遍算出来的一样', () => {
const { root, cards } = page()
const layout = new PageLayout()
layout.attach(root, null)
layout.attach(root, null, () => PLACEMENT)
for (const y of [0, 50, 100, 310, 950, 1200, 1999, 2500]) {
const found = layout.anchorAt(y)
expect(found && { line: found.line, offset: found.offset }, `y ${y}`).toEqual((({ line, offset }) => ({ line, offset }))(anchorAt(cards, y)!))
@@ -74,7 +80,7 @@ describe('卡片位置量过就记着', () => {
it('钉住的卡片:只算和顶上那一段相交的顶层块,在编辑的不钉;外层卡片的下沿算到它的子层', () => {
const { root } = page()
const layout = new PageLayout()
layout.attach(root, null)
layout.attach(root, null, () => PLACEMENT)
window.scrollTo(0, 0)
const scopes = layout.stickyScopes(48)
expect(scopes.map(scope => [scope.id, scope.depth, scope.top, scope.bottom])).toEqual([['0', 0, 0, 900]])
@@ -83,7 +89,7 @@ describe('卡片位置量过就记着', () => {
it('滚动时不再量:同一份内容问几次都只量一次;只量用到的那几段;内容变了才重量', async () => {
const { root } = page()
const layout = new PageLayout()
layout.attach(root, null)
layout.attach(root, null, () => PLACEMENT)
layout.anchorAt(0)
// 三段顶层块的外框 + 第 0、1 段里的卡片和子层
const first = reads
@@ -101,7 +107,7 @@ describe('卡片位置量过就记着', () => {
it('要滚过去的:目标所在的顶层块连同上下几屏之内的先照常排版,过两帧放回去', async () => {
const { root } = page()
const layout = new PageLayout()
layout.attach(root, null)
layout.attach(root, null, () => PLACEMENT)
const items = [...root.querySelectorAll('.cr-item')]
expect(layout.cardForLine(40)?.line).toBe(40)
expect(items.map(item => item.hasAttribute('data-settle'))).toEqual([true, true, true])