Fix local filetree page tree open performance

This commit is contained in:
lix-2026
2026-05-27 12:53:55 +08:00
parent 3ae33cc21d
commit c01dc2dea2
10 changed files with 730 additions and 47 deletions
@@ -37,6 +37,9 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
};
var fileTreeState = fileTreeViewState;
var fileTreeExpandedRelativePaths = fileTreeViewState.expandedParents;
var pageTreeState = {
pageTreeRequestGeneration: 0
};
var fileTreeLazyCacheRootUri = '';
var fileTreeExpansionStorageRootUri = '';
var fileTreeExpansionRestoreTimer = 0;
@@ -660,6 +663,29 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
fileTreeState.dirtyParents.add(key);
}
function beginPageTreeRequest() {
pageTreeState.pageTreeRequestGeneration += 1;
return pageTreeState.pageTreeRequestGeneration;
}
function isLatestPageTreeRequest(generation) {
return generation === pageTreeState.pageTreeRequestGeneration;
}
function yieldForPageTreeRender() {
return new Promise(function(resolve) {
if (typeof window !== 'undefined' && typeof window.requestIdleCallback === 'function') {
window.requestIdleCallback(function() { resolve(); }, { timeout: 120 });
return;
}
if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {
window.requestAnimationFrame(function() { resolve(); });
return;
}
setTimeout(resolve, 0);
});
}
function pageTreeChevronSvg() {
return '<svg class="tree-toggle-icon" viewBox="0 0 20 20" width="20" height="20" aria-hidden="true" focusable="false"><path d="M7.84 14.955c.206 0 .37-.07.505-.21l4.277-4.179a.79.79 0 0 0 .264-.574.78.78 0 0 0-.258-.574L8.35 5.24a.7.7 0 0 0-.51-.21.721.721 0 0 0-.498 1.247l3.814 3.721-3.814 3.709a.721.721 0 0 0 .498 1.248"></path></svg>';
}
@@ -687,15 +713,26 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
}).join('');
}
function renderPageProjection(projection) {
async function renderPageProjection(projection) {
var generation = beginPageTreeRequest();
var tree = document.getElementById('sidebar-tree-root');
if (!tree) return false;
var rows = projectionItems(projection).filter(function(item) {
return String(item.rowKind || 'document') === 'document';
});
await yieldForPageTreeRender();
if (!isLatestPageTreeRequest(generation)) {
document.documentElement.setAttribute('data-mnote-page-tree-stale-projection-ignored', String(generation));
return false;
}
var activeId = currentDocumentId();
var activeRowId = currentFileTreeActiveRowId();
tree.innerHTML = '<ul class="tree-root" role="tree" data-rust-page-renderer="initial_v1">' + (rows.length ? renderPageRows('', groupRowsByParent(rows), activeId, 0) : '') + '</ul>';
var template = document.createElement('template');
template.innerHTML = '<ul class="tree-root" role="tree" data-rust-page-renderer="initial_v1">' + (rows.length ? renderPageRows('', groupRowsByParent(rows), activeId, 0) : '') + '</ul>';
if (!isLatestPageTreeRequest(generation)) {
document.documentElement.setAttribute('data-mnote-page-tree-stale-projection-ignored', String(generation));
return false;
}
tree.replaceChildren(template.content.cloneNode(true));
return true;
}
@@ -977,14 +1014,22 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
}
function renderSidebarSnapshot(payload) {
var renderedPage = hasProjectionItems(payload) ? renderPageProjection(payload) : false;
var renderedPage = false;
if (hasProjectionItems(payload)) {
renderedPage = true;
void renderPageProjection(payload);
}
var fileProjection = readDatasetProjection(payload, 'kernel_file_tree_projection', 'kernelFileTreeProjection');
var renderedFile = fileProjection && hasProjectionItems(fileProjection) ? renderFileProjection(fileProjection) : false;
return renderedPage || renderedFile;
}
function renderLiveSidebarSnapshot(payload) {
var renderedPage = hasProjectionItems(payload) ? renderPageProjection(payload) : false;
var renderedPage = false;
if (hasProjectionItems(payload)) {
renderedPage = true;
void renderPageProjection(payload);
}
var fileProjection = readDatasetProjection(payload, 'kernel_file_tree_projection', 'kernelFileTreeProjection');
var hasFileProjection = fileProjection && hasProjectionItems(fileProjection);
if (currentFileTreeScope()) {
@@ -1109,9 +1154,11 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
var sidebarPayload = sidebarResponse && sidebarResponse.ok ? await sidebarResponse.json().catch(function() { return null; }) : null;
var resolvedSidebarPayload = sidebarPayload ? (sidebarPayload.result || sidebarPayload) : null;
var renderedPage = resolvedSidebarPayload && hasProjectionItems(resolvedSidebarPayload)
? renderPageProjection(resolvedSidebarPayload)
: false;
var renderedPage = false;
if (resolvedSidebarPayload && hasProjectionItems(resolvedSidebarPayload)) {
renderedPage = true;
void renderPageProjection(resolvedSidebarPayload);
}
if (renderedFile && fileTreeScope) {
var fileRoot = document.getElementById('sidebar-file-tree-root');
if (fileRoot instanceof HTMLElement) fileRoot.setAttribute('data-mnote-filetree-scope', fileTreeScope);
@@ -735,26 +735,37 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
url.searchParams.set('sourceKind', 'local_folder');
url.searchParams.set('rootUri', rootUri);
url.searchParams.set('parentRelativePath', relativePath);
var sidebarResponse = await fetch(sidebarUrl.toString(), {
var sidebarRequest = fetch(sidebarUrl.toString(), {
method: 'GET',
credentials: 'include',
headers: { accept: 'application/json' },
cache: 'no-store'
});
var sidebarPayload = await sidebarResponse.json().catch(function() { return null; });
if (!sidebarResponse.ok) throw new Error(sidebarPayload && (sidebarPayload.error || sidebarPayload.message) || 'local_page_tree_failed_' + sidebarResponse.status);
var response = await fetch(url.toString(), {
var fileRequest = fetch(url.toString(), {
method: 'GET',
credentials: 'include',
headers: { accept: 'application/json' },
cache: 'no-store'
});
var response = await fileRequest;
var payload = await response.json().catch(function() { return null; });
if (!response.ok) throw new Error(payload && (payload.error || payload.message) || 'scoped_filetree_failed_' + response.status);
var sidebarProjection = sidebarPayload && (sidebarPayload.result || sidebarPayload) || {};
var fileProjection = payload && (payload.result || payload);
var rendered = renderSidebarSnapshot(Object.assign({}, sidebarProjection, {
dataset: Object.assign({}, sidebarProjection.dataset || {}, { kernel_file_tree_projection: fileProjection })
var renderedFile = renderSidebarSnapshot({
dataset: { kernel_file_tree_projection: fileProjection }
});
root = document.getElementById('sidebar-file-tree-root');
if (root instanceof HTMLElement) {
root.setAttribute('data-workspace-id', workspaceId);
root.setAttribute('data-mnote-filetree-scope', relativePath);
root.setAttribute('data-mnote-filetree-scope-title', row.textContent ? row.textContent.trim() : relativePath);
}
var sidebarResponse = await sidebarRequest;
var sidebarPayload = await sidebarResponse.json().catch(function() { return null; });
if (!sidebarResponse.ok) throw new Error(sidebarPayload && (sidebarPayload.error || sidebarPayload.message) || 'local_page_tree_failed_' + sidebarResponse.status);
var sidebarProjection = sidebarPayload && (sidebarPayload.result || sidebarPayload) || {};
var renderedPage = renderSidebarSnapshot(Object.assign({}, sidebarProjection, {
dataset: Object.assign({}, sidebarProjection.dataset || {})
}));
root = document.getElementById('sidebar-file-tree-root');
if (root instanceof HTMLElement) {
@@ -762,7 +773,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
root.setAttribute('data-mnote-filetree-scope', relativePath);
root.setAttribute('data-mnote-filetree-scope-title', row.textContent ? row.textContent.trim() : relativePath);
}
return rendered;
return renderedFile || renderedPage;
}
const sidebarFileTreeOpen = createSidebarFileTreeOpenRuntime({