@xingwangzhe/stalux 1.55.2 → 1.55.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xingwangzhe/stalux",
3
- "version": "1.55.2",
3
+ "version": "1.55.3",
4
4
  "description": "A powerful, modern Astro blog theme — use as template or install as plugin",
5
5
  "keywords": [
6
6
  "astro",
@@ -1,8 +1,36 @@
1
1
  import { initTocScrollSpy } from "../utils/toc-scrollspy";
2
2
  import { registerPageLifecycle } from "./page-runtime";
3
3
 
4
+ /**
5
+ * 目录高亮初始化会读取全部标题位置,强制一次完整布局:线上文章页实测
6
+ * 226ms 长任务(JS 仅 21ms,其余是 Style & Layout),正好落在 TBT 统计窗口内。
7
+ * 而读者进入文章后通常先看开头,滚到需要高亮的时机远晚于首屏,
8
+ * 因此把它放到空闲时段;2s 兜底保证页面持续繁忙时仍会初始化。
9
+ */
4
10
  registerPageLifecycle("toc-scrollspy", () => {
5
11
  const container = document.querySelector<HTMLElement>("[data-toc-active-class]");
6
12
  const activeClass = container?.dataset.tocActiveClass;
7
- return activeClass ? initTocScrollSpy(activeClass) : undefined;
13
+ if (!activeClass) return;
14
+ let cleanup: (() => void) | undefined;
15
+ let disposed = false;
16
+ const run = () => {
17
+ if (!disposed) cleanup = initTocScrollSpy(activeClass);
18
+ };
19
+ // 通过可选属性读取,避免 TS 把初始化值收窄成「必定存在」而报常真判断。
20
+ const idle = (
21
+ globalThis as {
22
+ requestIdleCallback?: (
23
+ callback: IdleRequestCallback,
24
+ options?: IdleRequestOptions,
25
+ ) => number;
26
+ }
27
+ ).requestIdleCallback;
28
+ const handle = idle ? idle(run, { timeout: 2000 }) : setTimeout(run, 300);
29
+ return () => {
30
+ disposed = true;
31
+ // requestIdleCallback 与 cancelIdleCallback 在支持后者的实现里总是成对出现。
32
+ if (idle) globalThis.cancelIdleCallback(handle as number);
33
+ else clearTimeout(handle as unknown as ReturnType<typeof setTimeout>);
34
+ cleanup?.();
35
+ };
8
36
  });