perf(desktop): lazy-load renderer routes and pause polling when hidden
Drop the eager Antd global import in favour of unplugin-vue-components on-demand resolution, async route components, defineAsyncComponent for the shell/login split, and a dynamic Modal import inside showClientActionError. Pair that with a visibility-aware runtime poller that stops the 15s snapshot refresh when the window is hidden and kicks off an immediate refresh on re-show. Refresh DesktopShell nav with inline icons and a calmer active/hover treatment, and land ActionButton/DisclosurePanel/PaginationBar primitives for upcoming views. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,12 +2,19 @@ import { computed, onMounted, onUnmounted, readonly, shallowRef } from "vue";
|
||||
|
||||
import type { DesktopRuntimeSnapshot } from "../types";
|
||||
|
||||
const RUNTIME_POLL_INTERVAL_MS = 15_000;
|
||||
|
||||
const snapshot = shallowRef<DesktopRuntimeSnapshot | null>(null);
|
||||
const loading = shallowRef(false);
|
||||
const error = shallowRef<string | null>(null);
|
||||
|
||||
let intervalHandle: ReturnType<typeof setInterval> | null = null;
|
||||
let subscribers = 0;
|
||||
let visibilityListenerBound = false;
|
||||
|
||||
function isPageVisible(): boolean {
|
||||
return typeof document === "undefined" || document.visibilityState === "visible";
|
||||
}
|
||||
|
||||
async function refreshRuntimeSnapshot() {
|
||||
loading.value = true;
|
||||
@@ -47,18 +54,8 @@ async function refreshAccounts() {
|
||||
}
|
||||
}
|
||||
|
||||
function startPolling() {
|
||||
if (intervalHandle) {
|
||||
return;
|
||||
}
|
||||
|
||||
intervalHandle = setInterval(() => {
|
||||
void refreshRuntimeSnapshot();
|
||||
}, 15_000);
|
||||
}
|
||||
|
||||
function stopPolling() {
|
||||
if (subscribers > 0 || !intervalHandle) {
|
||||
if (!intervalHandle) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -66,18 +63,66 @@ function stopPolling() {
|
||||
intervalHandle = null;
|
||||
}
|
||||
|
||||
function syncPollingState() {
|
||||
if (subscribers === 0 || !isPageVisible()) {
|
||||
stopPolling();
|
||||
return;
|
||||
}
|
||||
|
||||
if (intervalHandle) {
|
||||
return;
|
||||
}
|
||||
|
||||
intervalHandle = setInterval(() => {
|
||||
void refreshRuntimeSnapshot();
|
||||
}, RUNTIME_POLL_INTERVAL_MS);
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
if (isPageVisible()) {
|
||||
void refreshRuntimeSnapshot();
|
||||
}
|
||||
|
||||
syncPollingState();
|
||||
}
|
||||
|
||||
function bindVisibilityListener() {
|
||||
if (visibilityListenerBound || typeof document === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
document.addEventListener("visibilitychange", handleVisibilityChange);
|
||||
visibilityListenerBound = true;
|
||||
}
|
||||
|
||||
function unbindVisibilityListener() {
|
||||
if (!visibilityListenerBound || typeof document === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||
visibilityListenerBound = false;
|
||||
}
|
||||
|
||||
export function useDesktopRuntime() {
|
||||
onMounted(() => {
|
||||
subscribers += 1;
|
||||
bindVisibilityListener();
|
||||
if (!snapshot.value && !loading.value) {
|
||||
void refreshRuntimeSnapshot();
|
||||
}
|
||||
startPolling();
|
||||
syncPollingState();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
subscribers = Math.max(0, subscribers - 1);
|
||||
stopPolling();
|
||||
if (subscribers === 0) {
|
||||
stopPolling();
|
||||
unbindVisibilityListener();
|
||||
return;
|
||||
}
|
||||
|
||||
syncPollingState();
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user