Remove dashboard prewarm requests

This commit is contained in:
2569718930@qq.com
2026-04-15 15:51:08 +08:00
parent aa6ed30987
commit c55b83a134
3 changed files with 7 additions and 214 deletions
+1 -13
View File
@@ -5,7 +5,7 @@ import clsx from "clsx";
import { useRouter } from "next/navigation";
import { useEffect, useMemo, useRef, useState } from "react";
import { ForecastTable } from "@/components/dashboard/PanelSections";
import { preloadChartJs, useChart } from "@/hooks/useChart";
import { useChart } from "@/hooks/useChart";
import { useDashboardStore } from "@/hooks/useDashboardStore";
import { useI18n } from "@/hooks/useI18n";
import { getOfficialSourceLinks } from "@/lib/dashboard-official-sources";
@@ -360,12 +360,6 @@ export function DetailPanel() {
: `${t("detail.todayAnalysis")} (Pro)`
}
onClick={() => handleFeatureAccess("today")}
onFocus={() => {
void preloadChartJs();
}}
onMouseEnter={() => {
void preloadChartJs();
}}
disabled={!store.selectedCity}
>
{isPro
@@ -379,12 +373,6 @@ export function DetailPanel() {
isPro ? t("detail.history") : `${t("detail.history")} (Pro)`
}
onClick={() => handleFeatureAccess("history")}
onFocus={() => {
void preloadChartJs();
}}
onMouseEnter={() => {
void preloadChartJs();
}}
disabled={!store.selectedCity}
>
{isPro ? t("detail.history") : `${t("detail.history")} · Pro`}
@@ -6,7 +6,6 @@ import {
DashboardStoreProvider,
useDashboardStore,
} from "@/hooks/useDashboardStore";
import { preloadChartJs } from "@/hooks/useChart";
import { I18nProvider, useI18n } from "@/hooks/useI18n";
import { CitySidebar } from "@/components/dashboard/CitySidebar";
import { DetailPanel } from "@/components/dashboard/DetailPanel";
@@ -82,42 +81,6 @@ function DashboardScreen() {
};
}, [store]);
useEffect(() => {
const browserWindow = window as Window & {
requestIdleCallback?: (
cb: IdleRequestCallback,
options?: IdleRequestOptions,
) => number;
cancelIdleCallback?: (handle: number) => void;
};
if (typeof browserWindow.requestIdleCallback === "function") {
const handle = browserWindow.requestIdleCallback(() => {
void loadHistoryModal();
void loadFutureForecastModal();
}, { timeout: 1200 });
return () => {
if (typeof browserWindow.cancelIdleCallback === "function") {
browserWindow.cancelIdleCallback(handle);
}
};
}
const timeoutId = window.setTimeout(() => {
void loadHistoryModal();
void loadFutureForecastModal();
}, 500);
return () => {
window.clearTimeout(timeoutId);
};
}, []);
useEffect(() => {
if (!store.selectedCity) return;
void preloadChartJs();
void loadHistoryModal();
void loadFutureForecastModal();
}, [store.selectedCity]);
// Avoid full-page flashing on initial load; only show this overlay for manual refresh.
const showLoading =
store.loadingState.cities ||
+6 -164
View File
@@ -101,38 +101,6 @@ function getMarketScanCacheKey(cityName: string, targetDate?: string | null) {
const SELECTED_CITY_STORAGE_KEY = "polyWeather_selected_city_v1";
const BACKGROUND_SUMMARY_REFRESH_MS = 30_000;
const EAGER_CITY_SUMMARIES_DISABLED =
process.env.NEXT_PUBLIC_POLYWEATHER_DISABLE_EAGER_SUMMARIES === "true";
const EAGER_SUMMARY_PRIORITY_CONCURRENCY = 3;
const EAGER_SUMMARY_BACKGROUND_CONCURRENCY = 2;
const EAGER_SUMMARY_BACKGROUND_IDLE_TIMEOUT_MS = 1200;
const EAGER_SUMMARY_PRIORITY_CITY_ORDER = [
"hong kong",
"taipei",
"shanghai",
"beijing",
"wuhan",
"shenzhen",
"chengdu",
"chongqing",
"seoul",
"busan",
"tokyo",
"singapore",
"kuala lumpur",
"jakarta",
"tel aviv",
"jeddah",
"istanbul",
"moscow",
"helsinki",
"warsaw",
"amsterdam",
"london",
"paris",
"milan",
"madrid",
] as const;
type CityDetailDepth = "panel" | "market" | "nearby" | "full";
function countAvailableModels(
@@ -291,57 +259,6 @@ function mergeCityDetail(
};
}
function getStoredSelectedCityName(cities: CityListItem[]) {
if (typeof window === "undefined") return null;
const stored = String(
window.localStorage.getItem(SELECTED_CITY_STORAGE_KEY) || "",
)
.trim()
.toLowerCase();
if (!stored) return null;
if (!cities.some((city) => city.name === stored)) return null;
return stored;
}
function getPriorityPreloadCities(cities: CityListItem[]) {
const citySet = new Set(cities.map((city) => city.name));
return EAGER_SUMMARY_PRIORITY_CITY_ORDER.filter((cityName) =>
citySet.has(cityName)
);
}
function scheduleWhenBrowserIdle(callback: () => void) {
if (typeof window === "undefined") {
callback();
return () => {};
}
const browserWindow = window as Window & {
requestIdleCallback?: (
cb: IdleRequestCallback,
options?: IdleRequestOptions,
) => number;
cancelIdleCallback?: (handle: number) => void;
};
if (typeof browserWindow.requestIdleCallback === "function") {
const handle = browserWindow.requestIdleCallback(
() => callback(),
{ timeout: EAGER_SUMMARY_BACKGROUND_IDLE_TIMEOUT_MS },
);
return () => {
if (typeof browserWindow.cancelIdleCallback === "function") {
browserWindow.cancelIdleCallback(handle);
}
};
}
const timeoutId = window.setTimeout(callback, 400);
return () => {
window.clearTimeout(timeoutId);
};
}
function toHistoryMeta(payload: HistoryPayload): HistoryPayloadMeta {
const history = Array.isArray(payload.history) ? payload.history : [];
const previewCount = Number(payload.preview_count || history.length || 0);
@@ -844,75 +761,6 @@ export function DashboardStoreProvider({
proAccess.userId,
]);
useEffect(() => {
if (EAGER_CITY_SUMMARIES_DISABLED) return;
if (!cities.length) return;
if (loadingState.refresh) return;
const priorityQueue: string[] = [];
const backgroundQueue: string[] = [];
const queued = new Set<string>();
const enqueue = (cityName: string | null, queue: string[]) => {
if (!cityName || queued.has(cityName) || citySummariesRef.current[cityName]) {
return;
}
queued.add(cityName);
queue.push(cityName);
};
enqueue(getStoredSelectedCityName(cities), priorityQueue);
getPriorityPreloadCities(cities).forEach((cityName) => {
enqueue(cityName, priorityQueue);
});
cities.forEach((city) => {
enqueue(city.name, backgroundQueue);
});
if (!priorityQueue.length && !backgroundQueue.length) return;
let active = true;
let cancelIdleSchedule = () => {};
const runQueue = async (queue: string[], concurrency: number) => {
if (!queue.length) return;
let cursor = 0;
const worker = async () => {
while (active && cursor < queue.length) {
const cityName = queue[cursor];
cursor += 1;
if (citySummariesRef.current[cityName]) continue;
try {
await ensureCitySummary(cityName);
} catch {}
}
};
await Promise.all(
Array.from({ length: Math.min(concurrency, queue.length) }, () =>
worker()
),
);
};
void (async () => {
await runQueue(priorityQueue, EAGER_SUMMARY_PRIORITY_CONCURRENCY);
if (!active) return;
if (isMapInteracting) return;
cancelIdleSchedule = scheduleWhenBrowserIdle(() => {
if (!active || isMapInteracting) return;
void runQueue(
backgroundQueue,
EAGER_SUMMARY_BACKGROUND_CONCURRENCY,
);
});
})();
return () => {
active = false;
cancelIdleSchedule();
};
}, [cities, isMapInteracting, loadingState.refresh]);
const selectCity = async (cityName: string) => {
setSelectedCity(cityName);
setIsPanelOpen(true);
@@ -961,16 +809,6 @@ export function DashboardStoreProvider({
.then((detail) => {
if (selectedCityRef.current !== cityName) return;
setSelectedForecastDate(detail.local_date);
if (access.authenticated && access.subscriptionActive) {
void ensureCityDetail(cityName, false, "market").catch(() => {});
// 预热市场数据,不做 await 阻塞,后台静默拉取
void ensureCityMarketScan(
cityName,
false,
null,
detail.local_date,
).catch(() => {});
}
})
.finally(() => {
if (selectedCityRef.current !== cityName) return;
@@ -1002,8 +840,12 @@ export function DashboardStoreProvider({
)
.trim()
.toLowerCase();
if (!stored) return;
if (!cities.some((city) => city.name === stored)) return;
if (!stored) {
return;
}
if (!cities.some((city) => city.name === stored)) {
return;
}
void selectCity(stored);
}, [cities, selectedCity, selectCity]);