perf: optimize polling, stats cache, and frontend chunk splitting
This commit is contained in:
@@ -532,6 +532,17 @@ function bindSocket() {
|
||||
|
||||
let unbindSocket = null
|
||||
let statsTimer = null
|
||||
let kdocsStatusTimer = null
|
||||
|
||||
const STATS_POLL_ACTIVE_MS = 10_000
|
||||
const STATS_POLL_HIDDEN_MS = 30_000
|
||||
const KDOCS_STATUS_POLL_ACTIVE_MS = 60_000
|
||||
const KDOCS_STATUS_POLL_HIDDEN_MS = 180_000
|
||||
|
||||
function isPageHidden() {
|
||||
if (typeof document === 'undefined') return false
|
||||
return document.visibilityState === 'hidden'
|
||||
}
|
||||
|
||||
const shouldPollStats = computed(() => {
|
||||
// 仅在“真正执行中”才轮询(排队中不轮询,避免空转导致页面闪烁)
|
||||
@@ -543,15 +554,27 @@ const shouldPollStats = computed(() => {
|
||||
})
|
||||
})
|
||||
|
||||
function currentStatsPollDelay() {
|
||||
return isPageHidden() ? STATS_POLL_HIDDEN_MS : STATS_POLL_ACTIVE_MS
|
||||
}
|
||||
|
||||
function stopStatsPolling() {
|
||||
if (!statsTimer) return
|
||||
window.clearInterval(statsTimer)
|
||||
window.clearTimeout(statsTimer)
|
||||
statsTimer = null
|
||||
}
|
||||
|
||||
function scheduleStatsPolling() {
|
||||
if (statsTimer || !shouldPollStats.value) return
|
||||
statsTimer = window.setTimeout(async () => {
|
||||
statsTimer = null
|
||||
await refreshStats({ silent: true }).catch(() => {})
|
||||
scheduleStatsPolling()
|
||||
}, currentStatsPollDelay())
|
||||
}
|
||||
|
||||
function startStatsPolling() {
|
||||
if (statsTimer) return
|
||||
statsTimer = window.setInterval(() => refreshStats({ silent: true }), 10_000)
|
||||
scheduleStatsPolling()
|
||||
}
|
||||
|
||||
function syncStatsPolling(prevRunning = null) {
|
||||
@@ -564,11 +587,37 @@ function syncStatsPolling(prevRunning = null) {
|
||||
else stopStatsPolling()
|
||||
}
|
||||
|
||||
watch(shouldPollStats, (running, prevRunning) => {
|
||||
watch(shouldPollStats, (_running, prevRunning) => {
|
||||
syncStatsPolling(prevRunning)
|
||||
})
|
||||
|
||||
let kdocsStatusTimer = null
|
||||
function currentKdocsStatusPollDelay() {
|
||||
return isPageHidden() ? KDOCS_STATUS_POLL_HIDDEN_MS : KDOCS_STATUS_POLL_ACTIVE_MS
|
||||
}
|
||||
|
||||
function stopKdocsStatusPolling() {
|
||||
if (!kdocsStatusTimer) return
|
||||
window.clearTimeout(kdocsStatusTimer)
|
||||
kdocsStatusTimer = null
|
||||
}
|
||||
|
||||
function scheduleKdocsStatusPolling() {
|
||||
if (kdocsStatusTimer) return
|
||||
kdocsStatusTimer = window.setTimeout(async () => {
|
||||
kdocsStatusTimer = null
|
||||
await loadKdocsStatus().catch(() => {})
|
||||
scheduleKdocsStatusPolling()
|
||||
}, currentKdocsStatusPollDelay())
|
||||
}
|
||||
|
||||
function restartTimedPollingOnVisibilityChange() {
|
||||
if (shouldPollStats.value) {
|
||||
stopStatsPolling()
|
||||
startStatsPolling()
|
||||
}
|
||||
stopKdocsStatusPolling()
|
||||
scheduleKdocsStatusPolling()
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (!userStore.vipInfo) {
|
||||
@@ -583,16 +632,17 @@ onMounted(async () => {
|
||||
await loadKdocsSettings()
|
||||
await loadKdocsStatus()
|
||||
await refreshStats()
|
||||
syncStatsPolling()
|
||||
|
||||
// 每60秒刷新 KDocs 状态
|
||||
kdocsStatusTimer = window.setInterval(() => loadKdocsStatus(), 60_000)
|
||||
syncStatsPolling()
|
||||
scheduleKdocsStatusPolling()
|
||||
window.addEventListener('visibilitychange', restartTimedPollingOnVisibilityChange)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (unbindSocket) unbindSocket()
|
||||
stopStatsPolling()
|
||||
if (kdocsStatusTimer) window.clearInterval(kdocsStatusTimer)
|
||||
stopKdocsStatusPolling()
|
||||
window.removeEventListener('visibilitychange', restartTimedPollingOnVisibilityChange)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user