diff --git a/src/components/profile/profile-box.tsx b/src/components/profile/profile-box.tsx
index a0fc4a160cc097d3b878dbf786f0458a4da677e9..6e15a879ad3622975702cdda50ef24c88cc44b71 100644
--- a/src/components/profile/profile-box.tsx
+++ b/src/components/profile/profile-box.tsx
@@ -27,6 +27,7 @@ export const ProfileBox = styled(Box)(
     }[key]!;
 
     return {
+      position: "relative",
       width: "100%",
       display: "block",
       cursor: "pointer",
diff --git a/src/components/profile/profile-item.tsx b/src/components/profile/profile-item.tsx
index b3703079b851af8a1197a269f7b83e7682a66649..72fda6f0f074919cb094df86ffdcee3bec4e9945 100644
--- a/src/components/profile/profile-item.tsx
+++ b/src/components/profile/profile-item.tsx
@@ -12,6 +12,7 @@ import {
   keyframes,
   MenuItem,
   Menu,
+  CircularProgress,
 } from "@mui/material";
 import { RefreshRounded } from "@mui/icons-material";
 import { atomLoadingCache } from "@/services/states";
@@ -28,13 +29,14 @@ const round = keyframes`
 
 interface Props {
   selected: boolean;
+  activating: boolean;
   itemData: IProfileItem;
   onSelect: (force: boolean) => void;
   onEdit: () => void;
 }
 
 export const ProfileItem = (props: Props) => {
-  const { selected, itemData, onSelect, onEdit } = props;
+  const { selected, activating, itemData, onSelect, onEdit } = props;
 
   const { t } = useTranslation();
   const [anchorEl, setAnchorEl] = useState<any>(null);
@@ -192,6 +194,25 @@ export const ProfileItem = (props: Props) => {
           event.preventDefault();
         }}
       >
+        {activating && (
+          <Box
+            sx={{
+              position: "absolute",
+              display: "flex",
+              justifyContent: "center",
+              alignItems: "center",
+              top: 10,
+              left: 10,
+              right: 10,
+              bottom: 2,
+              zIndex: 10,
+              backdropFilter: "blur(2px)",
+            }}
+          >
+            <CircularProgress size={20} />
+          </Box>
+        )}
+
         <Box position="relative">
           <Typography
             width="calc(100% - 36px)"
diff --git a/src/pages/profiles.tsx b/src/pages/profiles.tsx
index 1c10126b3d7fed3d83faae3277f445aed6406d7b..0c48d15624ed9fee6f5747c1efc8037b40159099 100644
--- a/src/pages/profiles.tsx
+++ b/src/pages/profiles.tsx
@@ -35,6 +35,7 @@ const ProfilePage = () => {
 
   const [url, setUrl] = useState("");
   const [disabled, setDisabled] = useState(false);
+  const [activating, setActivating] = useState("");
 
   const {
     profiles = {},
@@ -99,6 +100,8 @@ const ProfilePage = () => {
 
   const onSelect = useLockFn(async (current: string, force: boolean) => {
     if (!force && current === profiles.current) return;
+    // 避免大多数情况下loading态闪烁
+    const reset = setTimeout(() => setActivating(current), 100);
     try {
       await patchProfiles({ current });
       mutateLogs();
@@ -107,6 +110,9 @@ const ProfilePage = () => {
       Notice.success("Refresh clash config", 1000);
     } catch (err: any) {
       Notice.error(err?.message || err.toString(), 4000);
+    } finally {
+      clearTimeout(reset);
+      setActivating("");
     }
   });
 
@@ -258,6 +264,7 @@ const ProfilePage = () => {
             <Grid item xs={12} sm={6} md={4} lg={3} key={item.file}>
               <ProfileItem
                 selected={profiles.current === item.uid}
+                activating={activating === item.uid}
                 itemData={item}
                 onSelect={(f) => onSelect(item.uid, f)}
                 onEdit={() => viewerRef.current?.edit(item)}