perf(web): optimize API polling frequency and respect page visibility
This commit is contained in:
@@ -37,8 +37,9 @@ function handleNodeChange(val: any) {
|
||||
|
||||
function startPolling() {
|
||||
stopPolling()
|
||||
if (document.visibilityState === 'hidden') return
|
||||
loadNodes()
|
||||
timer = setInterval(loadNodes, 30000)
|
||||
timer = setInterval(loadNodes, 120000) // 放宽至 2 分钟一次
|
||||
}
|
||||
|
||||
function stopPolling() {
|
||||
@@ -48,6 +49,16 @@ function stopPolling() {
|
||||
}
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
if (document.visibilityState === 'visible') {
|
||||
if (isMaster.value) {
|
||||
startPolling()
|
||||
}
|
||||
} else {
|
||||
stopPolling()
|
||||
}
|
||||
}
|
||||
|
||||
async function checkRoleAndInit() {
|
||||
try {
|
||||
const role = await api.settings.get('interconnect', 'interconnect_role')
|
||||
@@ -86,10 +97,12 @@ roleBus.on((newRole) => {
|
||||
|
||||
onMounted(async () => {
|
||||
await checkRoleAndInit()
|
||||
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
stopPolling()
|
||||
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@ import { api, type AppLog, LOG_CATEGORY, LOG_STATUS } from '@/api'
|
||||
import { toast } from 'vue-sonner'
|
||||
import { format } from 'date-fns'
|
||||
|
||||
import { eventBus } from '@/utils/event-bus'
|
||||
import { LOG_EVENTS } from '@/constants'
|
||||
|
||||
const notices = ref<AppLog[]>([])
|
||||
const unreadCount = ref(0)
|
||||
const loading = ref(false)
|
||||
@@ -56,12 +59,27 @@ async function markAllAsRead() {
|
||||
}
|
||||
|
||||
let timer: number
|
||||
let unsubscribe: () => void
|
||||
|
||||
onMounted(() => {
|
||||
fetchNotices()
|
||||
timer = window.setInterval(fetchNotices, 60000) // 每分钟拉取一次
|
||||
|
||||
// 订阅 WebSocket 实时事件,在收到新系统日志通知时主动刷新
|
||||
unsubscribe = eventBus.subscribe((msg) => {
|
||||
if (msg.type === LOG_EVENTS.ADDED) {
|
||||
const log = msg.payload
|
||||
if (log && log.category === LOG_CATEGORY.SYSTEM_NOTICE) {
|
||||
fetchNotices()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 10 分钟一次的长轮询作为断连兜底
|
||||
timer = window.setInterval(fetchNotices, 10 * 60 * 1000)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (unsubscribe) unsubscribe()
|
||||
if (timer) clearInterval(timer)
|
||||
})
|
||||
|
||||
|
||||
@@ -64,6 +64,16 @@ async function loadAgents() {
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshAgentsOnly() {
|
||||
if (document.visibilityState === 'hidden') return
|
||||
try {
|
||||
const agentList = await api.agents.list()
|
||||
agents.value = agentList
|
||||
} catch (e) {
|
||||
console.error('Failed to poll agent status', e)
|
||||
}
|
||||
}
|
||||
|
||||
// Handler functions for Agent
|
||||
function viewDetail(agent: Agent) {
|
||||
agentDetailDialogRef.value?.openDialog(agent)
|
||||
@@ -103,13 +113,37 @@ function openEditToken(token: AgentToken) {
|
||||
editTokenDialogRef.value?.openEdit(token)
|
||||
}
|
||||
|
||||
function startPolling() {
|
||||
stopPolling()
|
||||
if (document.visibilityState === 'hidden') return
|
||||
refreshTimer = setInterval(refreshAgentsOnly, 30000) // 仅轮询 Agent 在线状态,频率放宽至 30s
|
||||
}
|
||||
|
||||
function stopPolling() {
|
||||
if (refreshTimer) {
|
||||
clearInterval(refreshTimer)
|
||||
refreshTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
if (document.visibilityState === 'visible') {
|
||||
refreshAgentsOnly()
|
||||
startPolling()
|
||||
} else {
|
||||
stopPolling()
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadAgents()
|
||||
refreshTimer = setInterval(loadAgents, 10000)
|
||||
startPolling()
|
||||
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (refreshTimer) clearInterval(refreshTimer)
|
||||
stopPolling()
|
||||
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user