From ce5505ea23a85e2f57c75fbe6a8301f90f10c6dd Mon Sep 17 00:00:00 2001 From: TerryM Date: Sat, 30 May 2026 02:46:26 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E9=A2=84=E7=83=AD=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E8=87=B3=E6=9C=80=E6=96=B0=E9=A1=B5,=E4=B8=B2=E8=A1=8C?= =?UTF-8?q?=E9=94=99=E5=B3=B0=E9=81=BF=E5=85=8D=E5=8D=A1=E9=A1=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 预热列表新增「最新」(/browse?sort=latest)。三个预取改为串行执行:每个在空闲 (requestIdleCallback)时触发、间隔 400ms,避免并发请求拖卡低端手机。仅 JSON。 Co-Authored-By: Claude Opus 4.8 (1M context) --- src/layouts/PublicLayout.tsx | 48 ++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/layouts/PublicLayout.tsx b/src/layouts/PublicLayout.tsx index 2eff651..684908a 100644 --- a/src/layouts/PublicLayout.tsx +++ b/src/layouts/PublicLayout.tsx @@ -294,29 +294,41 @@ export function PublicLayout() { // Current page name shown in the header brand slot (falls back to the brand). const pageTitle = usePageTitle(); - // Warm "全部资料" and "热门资料" in the background (when idle) so tapping them - // shows content immediately instead of loading on arrival. + // Warm the common stream views (全部资料 / 热门资料 / 最新) in the background so + // tapping them shows content immediately. Run one at a time, spaced out and + // only while idle, so prefetching never competes with the current page or + // janks low-end phones. Prefetch is JSON-only (no images). useEffect(() => { - const run = () => { - const base = { - scope: { kind: "all" as const }, - type: "all", - q: "", - lang, - }; - prefetchPostStream({ ...base, sort: "" }); - prefetchPostStream({ ...base, sort: "popular" }); - }; + const base = { scope: { kind: "all" as const }, type: "all", q: "", lang }; + const jobs = [ + () => prefetchPostStream({ ...base, sort: "" }), + () => prefetchPostStream({ ...base, sort: "popular" }), + () => prefetchPostStream({ ...base, sort: "latest" }), + ]; const ric = window as typeof window & { requestIdleCallback?: (cb: () => void) => number; cancelIdleCallback?: (id: number) => void; }; - if (ric.requestIdleCallback) { - const id = ric.requestIdleCallback(run); - return () => ric.cancelIdleCallback?.(id); - } - const id = window.setTimeout(run, 600); - return () => window.clearTimeout(id); + + let i = 0; + let stepTimer = 0; + let idleId = 0; + const runNext = () => { + if (i >= jobs.length) return; + jobs[i++](); + stepTimer = window.setTimeout(schedule, 400); // space requests apart + }; + const schedule = () => { + if (ric.requestIdleCallback) idleId = ric.requestIdleCallback(runNext); + else stepTimer = window.setTimeout(runNext, 200); + }; + + const startTimer = window.setTimeout(schedule, 600); + return () => { + window.clearTimeout(startTimer); + window.clearTimeout(stepTimer); + if (idleId) ric.cancelIdleCallback?.(idleId); + }; }, [lang]); const popularHref = "/browse?sort=popular";