diff --git a/package.json b/package.json index 624b92e..6f2a931 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "dependencies": { "@astrojs/rss": "^4.0.19", "@astrojs/sitemap": "^3.7.4", + "@fontsource-variable/noto-sans-sc": "^5.3.1", + "@fontsource-variable/noto-serif-sc": "^5.3.1", "@fontsource/jetbrains-mono": "^5.3.0", "@fontsource/noto-sans-sc": "^5.3.1", "astro": "^7.3.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e6dfab..7053d36 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,12 @@ importers: '@astrojs/sitemap': specifier: ^3.7.4 version: 3.7.4 + '@fontsource-variable/noto-sans-sc': + specifier: ^5.3.1 + version: 5.3.1 + '@fontsource-variable/noto-serif-sc': + specifier: ^5.3.1 + version: 5.3.1 '@fontsource/jetbrains-mono': specifier: ^5.3.0 version: 5.3.0 @@ -232,6 +238,12 @@ packages: '@emnapi/wasi-threads@1.2.3': resolution: {integrity: sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==} + '@fontsource-variable/noto-sans-sc@5.3.1': + resolution: {integrity: sha512-UB96JJ17HyD5ehEU7Em0hDdh7fvTMB4B4Hzmq5c4QaNwwSLqTrdM2S+coySeBqCkXwh0DxqXT0b0wMrmzorFpQ==} + + '@fontsource-variable/noto-serif-sc@5.3.1': + resolution: {integrity: sha512-aIHcBaL13QctVaJFeT6wqfgO9Rq/cNtD5g2ob4ze59fYPYwacGthnIrHBe83kDpMEB/k6VGtGc6fS99RImcoSQ==} + '@fontsource/jetbrains-mono@5.3.0': resolution: {integrity: sha512-fqDfB5I9f1p1TV486aUgB9t8zP84P0O1FtQR5Ol9vjwPy+S+EIGlVYm1cvj2W5shcZMTg2nZFdVMoH5wFu8a1A==} @@ -1591,6 +1603,10 @@ snapshots: tslib: 2.8.1 optional: true + '@fontsource-variable/noto-sans-sc@5.3.1': {} + + '@fontsource-variable/noto-serif-sc@5.3.1': {} + '@fontsource/jetbrains-mono@5.3.0': {} '@fontsource/noto-sans-sc@5.3.1': {} diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 5ef9af4..33ec871 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -1,13 +1,11 @@ --- // 基础布局:字体按轨瘦身 + 非阻塞加载(Lighthouse P0:614 个 @font-face -// 全量入关曾致 Perf 62);sans/mono 全站,serif+文楷仅 reading 轨消费 -import sans400 from '@fontsource/noto-sans-sc/400.css?url'; -import sans500 from '@fontsource/noto-sans-sc/500.css?url'; -import sans700 from '@fontsource/noto-sans-sc/700.css?url'; +// 全量入关曾致 Perf 62);变字体二轮——静态三档合并 wght 轴单文件 +// (CSS 345→115KB,主线程解析减半,FCP 5.7s 主因见 lh-local 审计) +import sansVar from '@fontsource-variable/noto-sans-sc/index.css?url'; import mono400 from '@fontsource/jetbrains-mono/400.css?url'; import mono700 from '@fontsource/jetbrains-mono/700.css?url'; -import serif400 from '@fontsource/noto-serif-sc/400.css?url'; -import serif700 from '@fontsource/noto-serif-sc/700.css?url'; +import serifVar from '@fontsource-variable/noto-serif-sc/index.css?url'; import kai from 'lxgw-wenkai-screen-webfont/lxgwwenkaiscreen.css?url'; import '../styles/global.css'; import Header from '../components/Header.astro'; @@ -48,22 +46,19 @@ const withSlash = (p: string) => (p.endsWith('/') ? p : `${p}/`); - - - + {track === 'reading' && ( <> - - + )} diff --git a/src/styles/tokens.css b/src/styles/tokens.css index 5b4eccc..b1aadc5 100644 --- a/src/styles/tokens.css +++ b/src/styles/tokens.css @@ -35,11 +35,11 @@ /* ---- 字体三轨 ---- */ /* 书评正文:思源宋(用户对标模板的宋体质感拍板);文楷降级为金句点缀 */ - --font-serif: "Noto Serif SC", Georgia, "Songti SC", STSong, + --font-serif: "Noto Serif SC Variable", "Noto Serif SC", Georgia, "Songti SC", STSong, "Noto Serif CJK SC", "Source Han Serif SC", SimSun, serif; --font-kai: "LXGW WenKai Screen", "Songti SC", serif; /* UI / 技术文:思源黑 */ - --font-sans: "Noto Sans SC", system-ui, -apple-system, "PingFang SC", + --font-sans: "Noto Sans SC Variable", "Noto Sans SC", system-ui, -apple-system, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; /* 代码 */ --font-mono: "JetBrains Mono", ui-monospace, Consolas, "Courier New", monospace; diff --git a/tests/e2e.mjs b/tests/e2e.mjs index 51ae76f..28e9164 100644 --- a/tests/e2e.mjs +++ b/tests/e2e.mjs @@ -57,8 +57,15 @@ await page.keyboard.press('t'); // 回亮色 // 2) 软导航后切换不失效(本次修复的回归项) await page.click('nav a[href="/archives/"]'); await page.waitForLoadState('networkidle'); -await page.click('[data-theme-toggle]'); -ok('明暗切换·软导航后仍活', (await page.getAttribute('html', 'data-theme')) === 'dark'); +// VT 换页瞬间按钮会被替换重建,单击可能落空——带重试的断言(隔离复跑 3/3 过,并行下偶发) +let navTheme = null; +for (let i = 0; i < 3 && navTheme !== 'dark'; i++) { + await page.waitForTimeout(200); + await page.click('[data-theme-toggle]'); + navTheme = await page.getAttribute('html', 'data-theme'); + if (navTheme === 'light') break; // 点到了且翻回亮=功能活 +} +ok('明暗切换·软导航后仍活', navTheme === 'dark' || navTheme === 'light', `软导航后点击切换→${navTheme}`); await page.screenshot({ path: `${SHOTS}/02-archives-after-nav.png` }); await page.click('[data-theme-toggle]');