mirror of
https://github.com/flash555588/ai-model-workbench.git
synced 2026-07-22 06:56:38 +00:00
Defer live preview widget mount until viewport
This commit is contained in:
parent
6b630d426c
commit
2248b73f36
4 changed files with 31 additions and 4 deletions
|
|
@ -13,7 +13,7 @@
|
|||
- Performance: register reading-mode `3d`/`3dgrid` code blocks through lightweight lazy handlers so heavy inline preview modules load only when a rendered block needs them.
|
||||
- Performance: serialize Live Preview and reading-mode model loads through an inline preview queue and defer `3dgrid` model preparation until the grid enters the viewport, reducing startup and multi-model I/O spikes.
|
||||
- Performance: defer Live Preview runtime imports for preview backends, annotation managers, conversion preparation, and load feedback until a visible embed actually starts loading.
|
||||
- Performance: register Live Preview embeds through a lightweight lazy widget so workspace startup no longer imports the full embed runtime before a model embed mounts.
|
||||
- Performance: register Live Preview embeds through a lightweight lazy widget so workspace startup no longer imports the full embed runtime before a model embed approaches the viewport.
|
||||
- Performance: lazy-load the full settings tab UI and model import modal so normal workspace startup only registers lightweight entry points.
|
||||
- Performance: combine model profile normalization and compact-state change detection into one pass, reducing startup work for large `data.json` registered-part lists.
|
||||
- Performance: reuse already-normalized registered part arrays while loading model profiles, avoiding repeated object allocation for compact `data.json` state.
|
||||
|
|
|
|||
2
main.js
2
main.js
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Lightweight CM6 extension for Live Preview embeds.
|
||||
* The full model widget is imported only when an embed is mounted into the DOM.
|
||||
* The full model widget is imported only when an embed approaches the viewport.
|
||||
*/
|
||||
|
||||
import type { App } from "obsidian";
|
||||
|
|
@ -25,6 +25,7 @@ function loadLivePreviewModule(): Promise<LivePreviewModule> {
|
|||
class LazyModelEmbedWidget extends WidgetType {
|
||||
private mountedWidget: LivePreviewWidget | null = null;
|
||||
private mountedDom: HTMLElement | null = null;
|
||||
private viewportObs: IntersectionObserver | null = null;
|
||||
private destroyed = false;
|
||||
|
||||
constructor(
|
||||
|
|
@ -75,13 +76,15 @@ class LazyModelEmbedWidget extends WidgetType {
|
|||
const placeholder = activeDocument.createElement("div");
|
||||
placeholder.className = "ai3d-embed-preview ai3d-cm-widget ai3d-embed-preview-lazy";
|
||||
placeholder.setAttribute("contenteditable", "false");
|
||||
placeholder.style.setProperty("--ai3d-embed-height", `${this.height}px`);
|
||||
|
||||
void this.mount(placeholder);
|
||||
this.watchViewport(placeholder);
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
override destroy(): void {
|
||||
this.destroyed = true;
|
||||
this.stopViewportWatch();
|
||||
this.mountedWidget?.destroy();
|
||||
this.mountedWidget = null;
|
||||
this.mountedDom?.remove();
|
||||
|
|
@ -92,6 +95,26 @@ class LazyModelEmbedWidget extends WidgetType {
|
|||
return true;
|
||||
}
|
||||
|
||||
private watchViewport(placeholder: HTMLElement): void {
|
||||
if (typeof IntersectionObserver === "undefined") {
|
||||
void this.mount(placeholder);
|
||||
return;
|
||||
}
|
||||
|
||||
this.viewportObs = new IntersectionObserver((entries) => {
|
||||
if (this.destroyed || this.mountedWidget) return;
|
||||
if (!entries.some((entry) => entry.isIntersecting || entry.intersectionRatio > 0)) return;
|
||||
this.stopViewportWatch();
|
||||
void this.mount(placeholder);
|
||||
}, { rootMargin: "240px" });
|
||||
this.viewportObs.observe(placeholder);
|
||||
}
|
||||
|
||||
private stopViewportWatch(): void {
|
||||
this.viewportObs?.disconnect();
|
||||
this.viewportObs = null;
|
||||
}
|
||||
|
||||
private async mount(placeholder: HTMLElement): Promise<void> {
|
||||
let module: LivePreviewModule;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -970,6 +970,10 @@ body {
|
|||
border-radius: var(--radius-m);
|
||||
}
|
||||
|
||||
.ai3d-embed-preview-lazy {
|
||||
min-height: var(--ai3d-embed-height, 300px);
|
||||
}
|
||||
|
||||
.ai3d-embed-canvas {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
|
|
|||
Loading…
Reference in a new issue