perf: optimize IP info card

This commit is contained in:
wonfen
2026-02-12 08:49:41 +08:00
parent 31c0910919
commit 81c56d46c1
4 changed files with 23 additions and 64 deletions
+10 -59
View File
@@ -137,62 +137,6 @@ const IP_CHECK_SERVICES: ServiceConfig[] = [
},
];
// 随机性服务列表洗牌函数
function shuffleServices() {
// 过滤无效服务并确保每个元素符合ServiceConfig接口
const validServices = IP_CHECK_SERVICES.filter(
(service): service is ServiceConfig =>
service !== null &&
service !== undefined &&
typeof service.url === "string" &&
typeof service.mapping === "function", // 添加对mapping属性的检查
);
if (validServices.length === 0) {
console.error("No valid services found in IP_CHECK_SERVICES");
return [];
}
// 使用单一Fisher-Yates洗牌算法,增强随机性
const shuffled = [...validServices];
const length = shuffled.length;
// 使用多个种子进行多次洗牌
const seeds = [Math.random(), Date.now() / 1000, performance.now() / 1000];
for (const seed of seeds) {
const prng = createPrng(seed);
// Fisher-Yates洗牌算法
for (let i = length - 1; i > 0; i--) {
const j = Math.floor(prng() * (i + 1));
// 使用临时变量进行交换,避免解构赋值可能的问题
const temp = shuffled[i];
shuffled[i] = shuffled[j];
shuffled[j] = temp;
}
}
return shuffled;
}
// 创建一个简单的随机数生成器
function createPrng(seed: number): () => number {
// 使用xorshift32算法
let state = seed >>> 0;
// 如果种子为0,设置一个默认值
if (state === 0) state = 123456789;
return function () {
state ^= state << 13;
state ^= state >>> 17;
state ^= state << 5;
return (state >>> 0) / 4294967296;
};
}
// 获取当前IP和地理位置信息
export const getIpInfo = async (): Promise<
IpInfo & { lastFetchTs: number }
@@ -201,7 +145,9 @@ export const getIpInfo = async (): Promise<
const maxRetries = 2;
const serviceTimeout = 5000;
const shuffledServices = shuffleServices();
const shuffledServices = IP_CHECK_SERVICES.toSorted(
() => Math.random() - 0.5,
);
let lastError: unknown | null = null;
const userAgent = await getUserAgentPromise();
console.debug("User-Agent for IP detection:", userAgent);
@@ -236,7 +182,12 @@ export const getIpInfo = async (): Promise<
);
}
const data = await response.json();
let data: any;
try {
data = await response.json();
} catch {
return bail(new Error(`无法解析 JSON 响应 from ${service.url}`));
}
if (data && data.ip) {
debugLog(`IP检测成功,使用服务: ${service.url}`);
@@ -245,7 +196,7 @@ export const getIpInfo = async (): Promise<
lastFetchTs: Date.now(),
});
} else {
throw new Error(`无效的响应格式 from ${service.url}`);
return bail(new Error(`无效的响应格式 from ${service.url}`));
}
},
{
+7
View File
@@ -26,3 +26,10 @@ export const SWR_MIHOMO = {
errorRetryInterval: 500,
errorRetryCount: 15,
};
export const SWR_EXTERNAL_API = {
...SWR_NOT_SMART,
shouldRetryOnError: true,
errorRetryCount: 1,
errorRetryInterval: 30_000,
} as const;