diff --git a/src/components/proxy/proxy-global.tsx b/src/components/proxy/proxy-global.tsx
index a6f5d46da730e93940b5c9abef44515eebca0c14..d741fed298934b5260bb4ea3b5ed669520ba8d3e 100644
--- a/src/components/proxy/proxy-global.tsx
+++ b/src/components/proxy/proxy-global.tsx
@@ -5,9 +5,8 @@ import { Virtuoso } from "react-virtuoso";
 import { providerHealthCheck, updateProxy } from "@/services/api";
 import { getProfiles, patchProfile } from "@/services/cmds";
 import delayManager from "@/services/delay";
-import useSortProxy from "./use-sort-proxy";
 import useHeadState from "./use-head-state";
-import useFilterProxy from "./use-filter-proxy";
+import useFilterSort from "./use-filter-sort";
 import ProxyHead from "./proxy-head";
 import ProxyItem from "./proxy-item";
 
@@ -27,14 +26,10 @@ const ProxyGlobal = (props: Props) => {
   const [headState, setHeadState] = useHeadState(groupName);
 
   const virtuosoRef = useRef<any>();
-  const filterProxies = useFilterProxy(
+  const sortedProxies = useFilterSort(
     proxies,
     groupName,
-    headState.filterText
-  );
-  const sortedProxies = useSortProxy(
-    filterProxies,
-    groupName,
+    headState.filterText,
     headState.sortType
   );
 
@@ -85,13 +80,12 @@ const ProxyGlobal = (props: Props) => {
     }
 
     await delayManager.checkListDelay(
-      {
-        names: sortedProxies.filter((p) => !p.provider).map((p) => p.name),
-        groupName,
-        skipNum: 16,
-      },
-      () => mutate("getProxies")
+      sortedProxies.filter((p) => !p.provider).map((p) => p.name),
+      groupName,
+      16
     );
+
+    mutate("getProxies");
   });
 
   useEffect(() => onLocation(false), [groupName]);
diff --git a/src/components/proxy/proxy-group.tsx b/src/components/proxy/proxy-group.tsx
index eb1b4c030a885909266b2e3d9e597891da613fe4..e21a6eefb0ab9e998c88f8a72f02dbe5c538acd6 100644
--- a/src/components/proxy/proxy-group.tsx
+++ b/src/components/proxy/proxy-group.tsx
@@ -18,9 +18,8 @@ import {
 import { providerHealthCheck, updateProxy } from "@/services/api";
 import { getProfiles, patchProfile } from "@/services/cmds";
 import delayManager from "@/services/delay";
-import useSortProxy from "./use-sort-proxy";
 import useHeadState from "./use-head-state";
-import useFilterProxy from "./use-filter-proxy";
+import useFilterSort from "./use-filter-sort";
 import ProxyHead from "./proxy-head";
 import ProxyItem from "./proxy-item";
 
@@ -35,14 +34,10 @@ const ProxyGroup = ({ group }: Props) => {
   const [headState, setHeadState] = useHeadState(group.name);
 
   const virtuosoRef = useRef<any>();
-  const filterProxies = useFilterProxy(
+  const sortedProxies = useFilterSort(
     group.all,
     group.name,
-    headState.filterText
-  );
-  const sortedProxies = useSortProxy(
-    filterProxies,
-    group.name,
+    headState.filterText,
     headState.sortType
   );
 
@@ -105,13 +100,12 @@ const ProxyGroup = ({ group }: Props) => {
     }
 
     await delayManager.checkListDelay(
-      {
-        names: sortedProxies.filter((p) => !p.provider).map((p) => p.name),
-        groupName: group.name,
-        skipNum: 16,
-      },
-      () => mutate("getProxies")
+      sortedProxies.filter((p) => !p.provider).map((p) => p.name),
+      group.name,
+      16
     );
+
+    mutate("getProxies");
   });
 
   // auto scroll to current index
diff --git a/src/components/proxy/proxy-head.tsx b/src/components/proxy/proxy-head.tsx
index f906b15e50c09a4dd5fdd6f8f0407657d1d4554a..b91f090876e1e4bdfb0dc67b750184fc0e04baa3 100644
--- a/src/components/proxy/proxy-head.tsx
+++ b/src/components/proxy/proxy-head.tsx
@@ -16,7 +16,7 @@ import {
 } from "@mui/icons-material";
 import delayManager from "@/services/delay";
 import type { HeadState } from "./use-head-state";
-import type { ProxySortType } from "./use-sort-proxy";
+import type { ProxySortType } from "./use-filter-sort";
 
 interface Props {
   sx?: SxProps;
diff --git a/src/components/proxy/proxy-item.tsx b/src/components/proxy/proxy-item.tsx
index b51681d4576df713008ec9c0e929251dab67b559..7ad6fbd52ba3aea29c63f9b965ccc0d6e608754b 100644
--- a/src/components/proxy/proxy-item.tsx
+++ b/src/components/proxy/proxy-item.tsx
@@ -49,6 +49,14 @@ const ProxyItem = (props: Props) => {
   // -2 为 loading
   const [delay, setDelay] = useState(-1);
 
+  useEffect(() => {
+    delayManager.setListener(proxy.name, groupName, setDelay);
+
+    return () => {
+      delayManager.removeListener(proxy.name, groupName);
+    };
+  }, [proxy.name, groupName]);
+
   useEffect(() => {
     if (!proxy) return;
 
@@ -66,10 +74,7 @@ const ProxyItem = (props: Props) => {
 
   const onDelay = useLockFn(async () => {
     setDelay(-2);
-    return delayManager
-      .checkDelay(proxy.name, groupName)
-      .then((result) => setDelay(result))
-      .catch(() => setDelay(1e6));
+    setDelay(await delayManager.checkDelay(proxy.name, groupName));
   });
 
   return (
diff --git a/src/components/proxy/use-filter-proxy.ts b/src/components/proxy/use-filter-proxy.ts
deleted file mode 100644
index 9ec8d3c06e4e8a7873e3e212ca01ff30607b2e90..0000000000000000000000000000000000000000
--- a/src/components/proxy/use-filter-proxy.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { useMemo } from "react";
-import delayManager from "@/services/delay";
-
-const regex1 = /delay([=<>])(\d+|timeout|error)/i;
-const regex2 = /type=(.*)/i;
-
-/**
- * filter the proxy
- * according to the regular conditions
- */
-export default function useFilterProxy(
-  proxies: ApiType.ProxyItem[],
-  groupName: string,
-  filterText: string
-) {
-  return useMemo(() => {
-    if (!proxies) return [];
-    if (!filterText) return proxies;
-
-    const res1 = regex1.exec(filterText);
-    if (res1) {
-      const symbol = res1[1];
-      const symbol2 = res1[2].toLowerCase();
-      const value =
-        symbol2 === "error" ? 1e5 : symbol2 === "timeout" ? 3000 : +symbol2;
-
-      return proxies.filter((p) => {
-        const delay = delayManager.getDelay(p.name, groupName);
-
-        if (delay < 0) return false;
-        if (symbol === "=" && symbol2 === "error") return delay >= 1e5;
-        if (symbol === "=" && symbol2 === "timeout")
-          return delay < 1e5 && delay >= 3000;
-        if (symbol === "=") return delay == value;
-        if (symbol === "<") return delay <= value;
-        if (symbol === ">") return delay >= value;
-        return false;
-      });
-    }
-
-    const res2 = regex2.exec(filterText);
-    if (res2) {
-      const type = res2[1].toLowerCase();
-      return proxies.filter((p) => p.type.toLowerCase().includes(type));
-    }
-
-    return proxies.filter((p) => p.name.includes(filterText.trim()));
-  }, [proxies, groupName, filterText]);
-}
diff --git a/src/components/proxy/use-filter-sort.ts b/src/components/proxy/use-filter-sort.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3171b0f86ed123ec026815e7b549d8bec585c806
--- /dev/null
+++ b/src/components/proxy/use-filter-sort.ts
@@ -0,0 +1,114 @@
+import { useEffect, useMemo, useState } from "react";
+import delayManager from "@/services/delay";
+
+// default | delay | alphabet
+export type ProxySortType = 0 | 1 | 2;
+
+export default function useFilterSort(
+  proxies: ApiType.ProxyItem[],
+  groupName: string,
+  filterText: string,
+  sortType: ProxySortType
+) {
+  const [refresh, setRefresh] = useState({});
+
+  useEffect(() => {
+    let last = 0;
+
+    delayManager.setGroupListener(groupName, () => {
+      // 简单节流
+      const now = Date.now();
+      if (now - last > 666) {
+        last = now;
+        setRefresh({});
+      }
+    });
+
+    return () => {
+      delayManager.removeGroupListener(groupName);
+    };
+  }, [groupName]);
+
+  return useMemo(() => {
+    const fp = filterProxies(proxies, groupName, filterText);
+    const sp = sortProxies(fp, groupName, sortType);
+    return sp;
+  }, [proxies, groupName, filterText, sortType, refresh]);
+}
+
+/**
+ * 可以通过延迟数/节点类型 过滤
+ */
+const regex1 = /delay([=<>])(\d+|timeout|error)/i;
+const regex2 = /type=(.*)/i;
+
+/**
+ * filter the proxy
+ * according to the regular conditions
+ */
+function filterProxies(
+  proxies: ApiType.ProxyItem[],
+  groupName: string,
+  filterText: string
+) {
+  if (!filterText) return proxies;
+
+  const res1 = regex1.exec(filterText);
+  if (res1) {
+    const symbol = res1[1];
+    const symbol2 = res1[2].toLowerCase();
+    const value =
+      symbol2 === "error" ? 1e5 : symbol2 === "timeout" ? 3000 : +symbol2;
+
+    return proxies.filter((p) => {
+      const delay = delayManager.getDelay(p.name, groupName);
+
+      if (delay < 0) return false;
+      if (symbol === "=" && symbol2 === "error") return delay >= 1e5;
+      if (symbol === "=" && symbol2 === "timeout")
+        return delay < 1e5 && delay >= 3000;
+      if (symbol === "=") return delay == value;
+      if (symbol === "<") return delay <= value;
+      if (symbol === ">") return delay >= value;
+      return false;
+    });
+  }
+
+  const res2 = regex2.exec(filterText);
+  if (res2) {
+    const type = res2[1].toLowerCase();
+    return proxies.filter((p) => p.type.toLowerCase().includes(type));
+  }
+
+  return proxies.filter((p) => p.name.includes(filterText.trim()));
+}
+
+/**
+ * sort the proxy
+ */
+function sortProxies(
+  proxies: ApiType.ProxyItem[],
+  groupName: string,
+  sortType: ProxySortType
+) {
+  if (!proxies) return [];
+  if (sortType === 0) return proxies;
+
+  const list = proxies.slice();
+
+  if (sortType === 1) {
+    list.sort((a, b) => {
+      const ad = delayManager.getDelay(a.name, groupName);
+      const bd = delayManager.getDelay(b.name, groupName);
+
+      if (ad === -1 || ad === -2) return 1;
+      if (bd === -1 || bd === -2) return -1;
+
+      return ad - bd;
+    });
+  } else {
+    list.sort((a, b) => a.name.localeCompare(b.name));
+  }
+
+  return list;
+}
diff --git a/src/components/proxy/use-head-state.ts b/src/components/proxy/use-head-state.ts
index 20e839e3b85f09063576fa37469f2b7500172f7e..5e2a6777fcbb4752f612602150fe3d590c580c99 100644
--- a/src/components/proxy/use-head-state.ts
+++ b/src/components/proxy/use-head-state.ts
@@ -1,7 +1,7 @@
 import { useCallback, useEffect, useState } from "react";
 import { useRecoilValue } from "recoil";
 import { atomCurrentProfile } from "@/services/states";
-import { ProxySortType } from "./use-sort-proxy";
+import { ProxySortType } from "./use-filter-sort";
 
 export interface HeadState {
   open?: boolean;
diff --git a/src/components/proxy/use-sort-proxy.ts b/src/components/proxy/use-sort-proxy.ts
deleted file mode 100644
index 0ed49b49a2b850eb6d9f0bf9fc8ab38614486962..0000000000000000000000000000000000000000
--- a/src/components/proxy/use-sort-proxy.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { useMemo } from "react";
-import delayManager from "@/services/delay";
-
-// default | delay | alpha
-export type ProxySortType = 0 | 1 | 2;
-
-/**
- * sort the proxy
- */
-export default function useSortProxy(
-  proxies: ApiType.ProxyItem[],
-  groupName: string,
-  sortType: ProxySortType
-) {
-  return useMemo(() => {
-    if (!proxies) return [];
-    if (sortType === 0) return proxies;
-
-    const list = proxies.slice();
-
-    if (sortType === 1) {
-      list.sort((a, b) => {
-        const ad = delayManager.getDelay(a.name, groupName);
-        const bd = delayManager.getDelay(b.name, groupName);
-
-        if (ad === -1 || ad === -2) return 1;
-        if (bd === -1 || bd === -2) return -1;
-
-        return ad - bd;
-      });
-    } else {
-      list.sort((a, b) => a.name.localeCompare(b.name));
-    }
-
-    return list;
-  }, [proxies, groupName, sortType]);
-}
diff --git a/src/services/delay.ts b/src/services/delay.ts
index ce7fcc42ba45c7469a4a7a5002ce9b77eec7c0a1..7c24b022b5784e6dab5a1a1dc597228fe950ae03 100644
--- a/src/services/delay.ts
+++ b/src/services/delay.ts
@@ -6,6 +6,12 @@ class DelayManager {
   private cache = new Map<string, [number, number]>();
   private urlMap = new Map<string, string>();
 
+  // 每个item的监听
+  private listenerMap = new Map<string, (time: number) => void>();
+
+  // 每个分组的监听
+  private groupListenerMap = new Map<string, () => void>();
+
   setUrl(group: string, url: string) {
     this.urlMap.set(group, url);
   }
@@ -14,8 +20,29 @@ class DelayManager {
     return this.urlMap.get(group);
   }
 
+  setListener(name: string, group: string, listener: (time: number) => void) {
+    const key = hashKey(name, group);
+    this.listenerMap.set(key, listener);
+  }
+
+  removeListener(name: string, group: string) {
+    const key = hashKey(name, group);
+    this.listenerMap.delete(key);
+  }
+
+  setGroupListener(group: string, listener: () => void) {
+    this.groupListenerMap.set(group, listener);
+  }
+
+  removeGroupListener(group: string) {
+    this.groupListenerMap.delete(group);
+  }
+
   setDelay(name: string, group: string, delay: number) {
-    this.cache.set(hashKey(name, group), [Date.now(), delay]);
+    const key = hashKey(name, group);
+    this.cache.set(key, [Date.now(), delay]);
+    this.listenerMap.get(key)?.(delay);
+    this.groupListenerMap.get(group)?.();
   }
 
   getDelay(name: string, group: string) {
@@ -44,19 +71,13 @@ class DelayManager {
   }
 
   async checkListDelay(
-    options: {
-      names: readonly string[];
-      groupName: string;
-      skipNum: number;
-    },
-    callback: Function
+    nameList: readonly string[],
+    groupName: string,
+    concurrency: number
   ) {
-    const { groupName, skipNum } = options;
-
-    const names = [...options.names];
-    const total = names.length;
+    const names = [...nameList];
 
-    let count = 0;
+    let total = names.length;
     let current = 0;
 
     // 设置正在延迟测试中
@@ -64,7 +85,7 @@ class DelayManager {
 
     return new Promise((resolve) => {
       const help = async (): Promise<void> => {
-        if (current >= skipNum) return;
+        if (current >= concurrency) return;
 
         const task = names.shift();
         if (!task) return;
@@ -72,14 +93,13 @@ class DelayManager {
         current += 1;
         await this.checkDelay(task, groupName);
         current -= 1;
+        total -= 1;
 
-        if (count++ % skipNum === 0 || count === total) callback();
-        if (count === total) resolve(null);
-
-        return help();
+        if (total <= 0) resolve(null);
+        else return help();
       };
 
-      for (let i = 0; i < skipNum; ++i) help();
+      for (let i = 0; i < concurrency; ++i) help();
     });
   }
 }