refactor(frontend): drop dead code in traffic and ws pipelines

Removes zero-consumer surface verified by repo-wide grep: the
reference-count render machinery, the never-called clearData chain,
unread snapshot fields (rangeMinutes, reason), dead refresh callbacks
on the connection hooks, the write-only wsRef sync, and the worker's
unreachable DEFAULT_CONFIG placeholder (now definite assignment under
the init-first client contract). No behavior change; the compressed
sampler path, samplerStats diagnostics, and lastTimestamp perf
contract stay. Net -120 lines across six files.
This commit is contained in:
Tunglies
2026-09-11 13:19:50 +08:00
parent 38c54c5b3b
commit 82d76113f2
6 changed files with 25 additions and 145 deletions
@@ -39,17 +39,6 @@ interface StatCardProps {
onClick?: () => void
}
// 全局变量类型定义
declare global {
interface Window {
animationFrameId?: number
lastTrafficData?: {
up: number
down: number
}
}
}
// 统计卡片组件 - 使用memo优化
const CompactStatCard = memo(
({ icon, title, value, unit, color, onClick }: StatCardProps) => {
-19
View File
@@ -258,7 +258,6 @@ const clearPendingMessage = () => {
interface SocketSupervisor {
start: () => void
stopIfIdle: () => void
reconnect: () => Promise<void>
}
const createSocketSupervisor = (options: {
@@ -349,7 +348,6 @@ const createSocketSupervisor = (options: {
clearReconnectTimer()
void closeSocket()
},
reconnect,
}
}
@@ -405,15 +403,6 @@ const subscribeConnectionSummary = (listener: ConnectionListener) => {
}
}
const refreshConnectionData = () => {
clearPendingMessage()
void connectionSupervisor.reconnect()
}
const refreshConnectionSummary = () => {
void summarySupervisor.reconnect()
}
const clearClosedConnectionData = () => {
if (connectionData.closedConnections.length === 0) return
connectionData = {
@@ -436,16 +425,12 @@ export const useConnectionData = (options?: { enabled?: boolean }) => {
getConnectionSnapshot,
)
const response = useMemo(() => ({ data }), [data])
const refreshGetClashConnection = useCallback(() => {
refreshConnectionData()
}, [])
const clearClosedConnections = useCallback(() => {
clearClosedConnectionData()
}, [])
return {
response,
refreshGetClashConnection,
clearClosedConnections,
}
}
@@ -463,12 +448,8 @@ export const useConnectionSummaryData = (options?: { enabled?: boolean }) => {
getConnectionSummarySnapshot,
)
const response = useMemo(() => ({ data }), [data])
const refreshGetClashConnectionSummary = useCallback(() => {
refreshConnectionSummary()
}, [])
return {
response,
refreshGetClashConnectionSummary,
}
}
+2 -18
View File
@@ -1,5 +1,5 @@
import { useLocalStorage } from 'foxact/use-local-storage'
import { type MutableRefObject, useCallback, useEffect, useRef } from 'react'
import { useCallback, useEffect, useRef } from 'react'
import { type Message, type MihomoWebSocket } from 'tauri-plugin-mihomo-api'
import {
@@ -22,7 +22,6 @@ interface SharedSubscriptionEntry {
ws: MihomoWebSocket | null
reconnectTimer: ReturnType<typeof setTimeout> | null
connecting: boolean
refHolders: Set<MutableRefObject<MihomoWebSocket | null>>
owners: Set<SharedSubscriptionOwner>
activeOwner: SharedSubscriptionOwner | null
closed: boolean
@@ -42,12 +41,6 @@ const writeSubscriptionSnapshot = <T>(key: string, data: T) => {
void setCacheData<T>([key], data)
}
const syncSharedWsRefs = (entry: SharedSubscriptionEntry) => {
entry.refHolders.forEach((ref) => {
ref.current = entry.ws
})
}
const pickActiveOwner = (entry: SharedSubscriptionEntry) => {
if (entry.activeOwner?.isMounted()) return entry.activeOwner
@@ -67,7 +60,6 @@ const closeSharedSocket = async (entry: SharedSubscriptionEntry) => {
if (!ws) return
entry.ws = null
syncSharedWsRefs(entry)
await ws.close()
}
@@ -79,7 +71,6 @@ const createSharedSubscriptionEntry = (
ws: null,
reconnectTimer: null,
connecting: false,
refHolders: new Set(),
owners: new Set(),
activeOwner: null,
closed: false,
@@ -121,7 +112,6 @@ const createSharedSubscriptionEntry = (
})
entry.ws = ws
syncSharedWsRefs(entry)
clearReconnectTimer()
} catch (ignoreError) {
if (!entry.closed && !entry.ws) {
@@ -207,8 +197,6 @@ export const useMihomoWsSubscription = <T>(
const responseCacheKey =
subscriptionCacheKey ?? lastSubscriptionCacheKeyRef.current
const wsRef = useRef<MihomoWebSocket | null>(null)
const resolveNextData = useCallback(
(
data: T | ((current?: T) => T | undefined) | undefined,
@@ -246,8 +234,6 @@ export const useMihomoWsSubscription = <T>(
}
entry.refs += 1
entry.refHolders.add(wsRef)
wsRef.current = entry.ws
let throttleCleanup: (() => void) | undefined
let wrappedNext: NextFn<T>
@@ -331,8 +317,6 @@ export const useMihomoWsSubscription = <T>(
return () => {
isMounted = false
entry.refHolders.delete(wsRef)
wsRef.current = null
entry.owners.delete(owner)
owner.cleanup?.()
@@ -376,5 +360,5 @@ export const useMihomoWsSubscription = <T>(
[responseCacheKey],
)
return { response, refresh, setData, wsRef }
return { response, refresh, setData }
}
+10 -54
View File
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useReducer, useRef, useState } from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { Traffic } from 'tauri-plugin-mihomo-api'
import { useVisibility } from '@/hooks/use-visibility'
@@ -8,33 +8,17 @@ import { TrafficDataSampler, isSameTrafficData } from '@/utils/traffic-sampler'
// 引用计数管理器
class ReferenceCounter {
private count = 0
private callbacks = new Set<() => void>()
private notify() {
this.callbacks.forEach((cb) => {
cb()
})
}
increment(): () => void {
this.count++
debugLog(`[ReferenceCounter] 引用计数增加: ${this.count}`)
this.notify()
return () => {
this.count--
debugLog(`[ReferenceCounter] 引用计数减少: ${this.count}`)
this.notify()
}
}
onCountChange(callback: () => void) {
this.callbacks.add(callback)
return () => this.callbacks.delete(callback)
}
getCount(): number {
return this.count
}
@@ -96,10 +80,10 @@ class InlineTrafficMonitor {
if (this.throttleTimer !== null) return
const slice = this.sampler.getDataForTimeRange(this.currentRange)
if (!isSameTrafficData(this.lastBroadcast, slice)) {
this.emitSnapshot('interval')
this.emitSnapshot()
}
}, 1000)
this.emitSnapshot('init')
this.emitSnapshot()
break
}
case 'append': {
@@ -112,24 +96,18 @@ class InlineTrafficMonitor {
this.lastTimestamp = timestamp
this.sampler.addDataPoint(dataPoint)
this.scheduleSnapshot('append-throttle')
break
}
case 'clear': {
this.sampler.clear()
this.lastTimestamp = undefined
this.emitSnapshot('clear')
this.scheduleSnapshot()
break
}
case 'setRange': {
if (this.currentRange !== message.minutes) {
this.currentRange = message.minutes
this.emitSnapshot('range-change')
this.emitSnapshot()
}
break
}
case 'requestSnapshot': {
this.emitSnapshot('request')
this.emitSnapshot()
break
}
default:
@@ -137,25 +115,23 @@ class InlineTrafficMonitor {
}
}
private emitSnapshot(reason: ITrafficWorkerSnapshotMessage['reason']) {
private emitSnapshot() {
const dataPoints = this.sampler.getDataForTimeRange(this.currentRange)
this.emit({
type: 'snapshot',
dataPoints,
samplerStats: this.sampler.getStats(),
rangeMinutes: this.currentRange,
lastTimestamp: this.lastTimestamp,
reason,
})
this.lastBroadcast = dataPoints
}
private scheduleSnapshot(reason: ITrafficWorkerSnapshotMessage['reason']) {
private scheduleSnapshot() {
if (this.throttleTimer !== null) return
this.throttleTimer = setTimeout(() => {
this.throttleTimer = null
this.emitSnapshot(reason)
this.emitSnapshot()
}, this.config.snapshotIntervalMs)
}
}
@@ -331,11 +307,6 @@ class TrafficWorkerClient {
})
}
clearData() {
this.ensureStarted()
this.post({ type: 'clear' })
}
setRange(minutes: number) {
this.currentRange = minutes
this.post({ type: 'setRange', minutes })
@@ -382,7 +353,6 @@ export const useTrafficMonitorEnhanced = (options?: {
dataPoints: [],
samplerStats: EMPTY_STATS,
})
const [, forceRefCountRender] = useReducer((value) => value + 1, 0)
const clientRef = useRef<TrafficWorkerClient | null>(getWorkerClient())
const currentRangeRef = useRef<number>(WORKER_CONFIG.defaultRangeMinutes)
@@ -396,9 +366,6 @@ export const useTrafficMonitorEnhanced = (options?: {
const client = getWorkerClient()
clientRef.current = client
const stopWatchRefCount = refCounter.onCountChange(() =>
forceRefCountRender(),
)
const cleanup = refCounter.increment()
client.start(currentRangeRef.current)
@@ -415,7 +382,6 @@ export const useTrafficMonitorEnhanced = (options?: {
return () => {
unsubscribe?.()
stopWatchRefCount()
cleanup()
if (refCounter.getCount() === 0) {
client.stop()
@@ -449,21 +415,13 @@ export const useTrafficMonitorEnhanced = (options?: {
[enabled],
)
// 清空数据
const clearData = useCallback(() => {
if (!enabled) return
clientRef.current?.clearData()
}, [enabled])
return {
graphData: {
dataPoints: enabled ? latestSnapshot.dataPoints : EMPTY_DATA,
requestRange,
appendData,
clearData,
},
samplerStats: latestSnapshot.samplerStats,
referenceCount: refCounter.getCount(),
}
}
@@ -471,12 +429,10 @@ export const useTrafficMonitorEnhanced = (options?: {
* 图表数据Hook
*/
export const useTrafficGraphDataEnhanced = () => {
const { graphData, samplerStats, referenceCount } =
useTrafficMonitorEnhanced()
const { graphData, samplerStats } = useTrafficMonitorEnhanced()
return {
...graphData,
samplerStats,
referenceCount,
}
}
+13 -30
View File
@@ -1,16 +1,5 @@
import { TrafficDataSampler, isSameTrafficData } from '../utils/traffic-sampler'
const DEFAULT_CONFIG: ISamplingConfig & {
snapshotIntervalMs: number
defaultRangeMinutes: number
} = {
rawDataMinutes: 10,
compressedDataMinutes: 60,
compressionRatio: 5,
snapshotIntervalMs: 250,
defaultRangeMinutes: 10,
}
interface WorkerScope {
postMessage: (message: unknown) => void
onmessage: ((event: MessageEvent<TrafficWorkerRequestMessage>) => void) | null
@@ -22,14 +11,16 @@ interface WorkerScope {
const ctx: WorkerScope = self as unknown as WorkerScope
let config = { ...DEFAULT_CONFIG }
let sampler = new TrafficDataSampler(config)
let currentRangeMinutes = config.defaultRangeMinutes
// 'init' is the first message posted by the client, so these are always
// assigned before first use.
let config!: ITrafficWorkerInitMessage['config']
let sampler!: TrafficDataSampler
let currentRangeMinutes!: number
let throttleTimer: ReturnType<typeof setTimeout> | null = null
let lastTimestamp: number | undefined
let lastBroadcast: ITrafficDataPoint[] = []
const broadcastSnapshot = (reason: ITrafficWorkerSnapshotMessage['reason']) => {
const broadcastSnapshot = () => {
const dataPoints = sampler.getDataForTimeRange(currentRangeMinutes)
const samplerStats = sampler.getStats()
@@ -37,20 +28,18 @@ const broadcastSnapshot = (reason: ITrafficWorkerSnapshotMessage['reason']) => {
type: 'snapshot',
dataPoints,
samplerStats,
rangeMinutes: currentRangeMinutes,
lastTimestamp,
reason,
}
ctx.postMessage(message)
lastBroadcast = dataPoints
}
const scheduleSnapshot = (reason: ITrafficWorkerSnapshotMessage['reason']) => {
const scheduleSnapshot = () => {
if (throttleTimer !== null) return
throttleTimer = ctx.setTimeout(() => {
throttleTimer = null
broadcastSnapshot(reason)
broadcastSnapshot()
}, config.snapshotIntervalMs)
}
@@ -68,10 +57,10 @@ ctx.onmessage = (event: MessageEvent<TrafficWorkerRequestMessage>) => {
if (throttleTimer !== null) return
const slice = sampler.getDataForTimeRange(currentRangeMinutes)
if (!isSameTrafficData(lastBroadcast, slice)) {
broadcastSnapshot('interval')
broadcastSnapshot()
}
}, 1000)
broadcastSnapshot('init')
broadcastSnapshot()
break
}
case 'append': {
@@ -84,24 +73,18 @@ ctx.onmessage = (event: MessageEvent<TrafficWorkerRequestMessage>) => {
lastTimestamp = timestamp
sampler.addDataPoint(dataPoint)
scheduleSnapshot('append-throttle')
break
}
case 'clear': {
sampler.clear()
lastTimestamp = undefined
broadcastSnapshot('clear')
scheduleSnapshot()
break
}
case 'setRange': {
if (currentRangeMinutes !== message.minutes) {
currentRangeMinutes = message.minutes
broadcastSnapshot('range-change')
broadcastSnapshot()
}
break
}
case 'requestSnapshot': {
broadcastSnapshot('request')
broadcastSnapshot()
break
}
default:
-13
View File
@@ -1005,10 +1005,6 @@ interface ITrafficWorkerAppendMessage {
}
}
interface ITrafficWorkerClearMessage {
type: 'clear'
}
interface ITrafficWorkerSetRangeMessage {
type: 'setRange'
minutes: number
@@ -1021,7 +1017,6 @@ interface ITrafficWorkerRequestSnapshotMessage {
type TrafficWorkerRequestMessage =
| ITrafficWorkerInitMessage
| ITrafficWorkerAppendMessage
| ITrafficWorkerClearMessage
| ITrafficWorkerSetRangeMessage
| ITrafficWorkerRequestSnapshotMessage
@@ -1029,15 +1024,7 @@ interface ITrafficWorkerSnapshotMessage {
type: 'snapshot'
dataPoints: ITrafficDataPoint[]
samplerStats: ISamplerStats
rangeMinutes: number
lastTimestamp?: number
reason:
| 'init'
| 'interval'
| 'range-change'
| 'request'
| 'append-throttle'
| 'clear'
}
interface ITrafficWorkerLogMessage {