feat(web-ui): pause dashboard polling, sockets, and chart updates when the tab is hidden

This commit is contained in:
2026-03-27 18:46:11 +00:00
parent 29d6076355
commit 6c4adf70c7
13 changed files with 367 additions and 292 deletions

View File

@@ -25,7 +25,7 @@ export class OpsViewCertificates extends DeesElement {
constructor() {
super();
const sub = appstate.certificateStatePart.state.subscribe((newState) => {
const sub = appstate.certificateStatePart.select().subscribe((newState) => {
this.certState = newState;
});
this.rxSubscriptions.push(sub);

View File

@@ -28,7 +28,7 @@ export class OpsViewEmails extends DeesElement {
async connectedCallback() {
await super.connectedCallback();
this.stateSubscription = appstate.emailOpsStatePart.state.subscribe((state) => {
this.stateSubscription = appstate.emailOpsStatePart.select().subscribe((state) => {
this.emails = state.emails;
this.isLoading = state.isLoading;
});

View File

@@ -47,10 +47,11 @@ export class OpsViewNetwork extends DeesElement {
// Track if we need to update the chart to avoid unnecessary re-renders
private lastChartUpdate = 0;
private chartUpdateThreshold = 1000; // Minimum ms between chart updates
private trafficUpdateTimer: any = null;
private requestsPerSecHistory: number[] = []; // Track requests/sec over time for trend
private historyLoaded = false; // Whether server-side throughput history has been loaded
private visibilityHandler: (() => void) | null = null;
constructor() {
super();
@@ -59,28 +60,42 @@ export class OpsViewNetwork extends DeesElement {
this.updateNetworkData();
this.startTrafficUpdateTimer();
}
async connectedCallback() {
await super.connectedCallback();
// Pause/resume traffic timer when tab visibility changes
this.visibilityHandler = () => {
if (document.hidden) {
this.stopTrafficUpdateTimer();
} else {
this.startTrafficUpdateTimer();
}
};
document.addEventListener('visibilitychange', this.visibilityHandler);
// When network view becomes visible, ensure we fetch network data
await appstate.networkStatePart.dispatchAction(appstate.fetchNetworkStatsAction, null);
}
async disconnectedCallback() {
await super.disconnectedCallback();
this.stopTrafficUpdateTimer();
if (this.visibilityHandler) {
document.removeEventListener('visibilitychange', this.visibilityHandler);
this.visibilityHandler = null;
}
}
private subscribeToStateParts() {
// Subscribe and track unsubscribe functions
const statsUnsubscribe = appstate.statsStatePart.state.subscribe((state) => {
const statsUnsubscribe = appstate.statsStatePart.select().subscribe((state) => {
this.statsState = state;
this.updateNetworkData();
});
this.rxSubscriptions.push(statsUnsubscribe);
const networkUnsubscribe = appstate.networkStatePart.state.subscribe((state) => {
const networkUnsubscribe = appstate.networkStatePart.select().subscribe((state) => {
this.networkState = state;
this.updateNetworkData();
});

View File

@@ -25,7 +25,7 @@ export class OpsViewRemoteIngress extends DeesElement {
constructor() {
super();
const sub = appstate.remoteIngressStatePart.state.subscribe((newState) => {
const sub = appstate.remoteIngressStatePart.select().subscribe((newState) => {
this.riState = newState;
});
this.rxSubscriptions.push(sub);