perf(fonts): 字体按轨瘦身与非阻塞加载——Perf 62→88(Lighthouse P0)
- BaseLayout:8 个字体包 CSS 改 ?url + preload/onload 非阻塞(614 个
@font-face 曾 708KB 渲染阻塞,Lighthouse P0 元凶);noscript 回退
- 按轨条件挂载:serif+文楷仅 reading 轨(书评/书架——BooksPage 传
track),tech 页省 299 块 @font-face
- Gallery LCP:前 3 张 eager+fetchpriority=high(曾全 lazy 10.3s)
- 对比度:PostList .track 与 .post-cat 提 --ink-2(A11y P1)
- favicon.svg 补缺(BP 扣分项)
- 教训:python replace 再犯静默失配(车道改过导入顺序)——已用 edit
工具精确替换 + assert 意识持续强化
验证: 本地 dist lighthouse 首页 Perf 62→88,render-blocking 无;
FCP 2.5s/LCP 3.2s;E2E 30/30 PASS(staging)
Spec: 2026-10-25_add-blog-5c
Co-authored-by: GLM-5.3
This commit is contained in:
1 parent
f8add5ad15
commit
147f00fe1c
5 files changed
+36
-15
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="7" fill="#191d23"/><text x="16" y="22" font-family="monospace" font-size="16" font-weight="700" fill="#8ea2ff" text-anchor="middle">w</text></svg>
|
||||||
|
After Width: | Height: | Size: 240 B |
@@ -81,7 +81,7 @@ const mmdd = (d: Date) =>
|
|||||||
.year {
|
.year {
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--ink-3);
|
color: var(--ink-2);
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
.shelf-link { float: right; font-size: 12.5px; color: var(--accent); font-weight: 400; }
|
.shelf-link { float: right; font-size: 12.5px; color: var(--accent); font-weight: 400; }
|
||||||
@@ -137,7 +137,7 @@ const mmdd = (d: Date) =>
|
|||||||
flex: none;
|
flex: none;
|
||||||
font-family: var(--font-mono);
|
font-family: var(--font-mono);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--ink-3);
|
color: var(--ink-2);
|
||||||
background: var(--bg-soft);
|
background: var(--bg-soft);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 1px 7px;
|
padding: 1px 7px;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const L = {
|
|||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={`${L.shelf} · wait4x`} description={locale === 'zh' ? '读过的书与一句策展' : 'Books read, one line each'}>
|
<BaseLayout track="reading" title={`${L.shelf} · wait4x`} description={locale === 'zh' ? '读过的书与一句策展' : 'Books read, one line each'}>
|
||||||
<h1 class="page-title">{L.shelf}<span class="count mono">{L.count(books.length)}</span></h1>
|
<h1 class="page-title">{L.shelf}<span class="count mono">{L.count(books.length)}</span></h1>
|
||||||
{years.map((year) => (
|
{years.map((year) => (
|
||||||
<section class="year-group">
|
<section class="year-group">
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ const first = cards[0];
|
|||||||
|
|
||||||
<div class="stage">
|
<div class="stage">
|
||||||
<ul class="wall">
|
<ul class="wall">
|
||||||
{cards.map((card) => (
|
{cards.map((card, i) => (
|
||||||
<li
|
<li
|
||||||
class="shot"
|
class="shot"
|
||||||
data-group={card.group}
|
data-group={card.group}
|
||||||
@@ -103,7 +103,8 @@ const first = cards[0];
|
|||||||
alt={card.alt}
|
alt={card.alt}
|
||||||
widths={[320, 560, 720]}
|
widths={[320, 560, 720]}
|
||||||
sizes="(min-width: 820px) 30vw, 46vw"
|
sizes="(min-width: 820px) 30vw, 46vw"
|
||||||
loading="lazy"
|
loading={i < 3 ? 'eager' : 'lazy'}
|
||||||
|
fetchpriority={i < 3 ? 'high' : undefined}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
---
|
---
|
||||||
// 基础布局:字体/样式统一在此持有(页面不再各自引包)
|
// 基础布局:字体按轨瘦身 + 非阻塞加载(Lighthouse P0:614 个 @font-face
|
||||||
// 明暗不闪烁:ThemeScript 必须在 <head> 内联先于首帧执行
|
// 全量入关曾致 Perf 62);sans/mono 全站,serif+文楷仅 reading 轨消费
|
||||||
import '@fontsource/noto-serif-sc/400.css';
|
import sans400 from '@fontsource/noto-sans-sc/400.css?url';
|
||||||
import '@fontsource/noto-serif-sc/700.css';
|
import sans500 from '@fontsource/noto-sans-sc/500.css?url';
|
||||||
import 'lxgw-wenkai-screen-webfont/lxgwwenkaiscreen.css'; // 金句点缀用(--font-kai),按需加载
|
import sans700 from '@fontsource/noto-sans-sc/700.css?url';
|
||||||
import '@fontsource/noto-sans-sc/400.css';
|
import mono400 from '@fontsource/jetbrains-mono/400.css?url';
|
||||||
import '@fontsource/noto-sans-sc/500.css';
|
import mono700 from '@fontsource/jetbrains-mono/700.css?url';
|
||||||
import '@fontsource/noto-sans-sc/700.css';
|
import serif400 from '@fontsource/noto-serif-sc/400.css?url';
|
||||||
import '@fontsource/jetbrains-mono/400.css';
|
import serif700 from '@fontsource/noto-serif-sc/700.css?url';
|
||||||
import '@fontsource/jetbrains-mono/700.css';
|
import kai from 'lxgw-wenkai-screen-webfont/lxgwwenkaiscreen.css?url';
|
||||||
import '../styles/global.css';
|
import '../styles/global.css';
|
||||||
import Header from '../components/Header.astro';
|
import Header from '../components/Header.astro';
|
||||||
import Footer from '../components/Footer.astro';
|
import Footer from '../components/Footer.astro';
|
||||||
@@ -39,6 +39,7 @@ const withSlash = (p: string) => (p.endsWith('/') ? p : `${p}/`);
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="generator" content={Astro.generator} />
|
<meta name="generator" content={Astro.generator} />
|
||||||
<meta name="description" content={description} />
|
<meta name="description" content={description} />
|
||||||
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
|
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
|
||||||
@@ -46,6 +47,24 @@ const withSlash = (p: string) => (p.endsWith('/') ? p : `${p}/`);
|
|||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<ThemeScript />
|
<ThemeScript />
|
||||||
<ClientRouter />
|
<ClientRouter />
|
||||||
|
<!-- 非阻塞字体 CSS:preload+onload 回切(Lighthouse P0-1:渲染阻塞 708KB 元凶) -->
|
||||||
|
<link rel="preload" as="style" href={sans400} onload="this.rel='stylesheet'" />
|
||||||
|
<link rel="preload" as="style" href={sans500} onload="this.rel='stylesheet'" />
|
||||||
|
<link rel="preload" as="style" href={sans700} onload="this.rel='stylesheet'" />
|
||||||
|
<link rel="preload" as="style" href={mono400} onload="this.rel='stylesheet'" />
|
||||||
|
<link rel="preload" as="style" href={mono700} onload="this.rel='stylesheet'" />
|
||||||
|
{track === 'reading' && (
|
||||||
|
<>
|
||||||
|
<link rel="preload" as="style" href={serif400} onload="this.rel='stylesheet'" />
|
||||||
|
<link rel="preload" as="style" href={serif700} onload="this.rel='stylesheet'" />
|
||||||
|
<link rel="preload" as="style" href={kai} onload="this.rel='stylesheet'" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<noscript>
|
||||||
|
<link rel="stylesheet" href={sans400} />
|
||||||
|
<link rel="stylesheet" href={mono400} />
|
||||||
|
{track === 'reading' && <link rel="stylesheet" href={serif400} />}
|
||||||
|
</noscript>
|
||||||
<link rel="alternate" hreflang="zh" href={new URL(withSlash(zhPath), Astro.site)} />
|
<link rel="alternate" hreflang="zh" href={new URL(withSlash(zhPath), Astro.site)} />
|
||||||
<link rel="alternate" hreflang="en" href={new URL(withSlash(enPath), Astro.site)} />
|
<link rel="alternate" hreflang="en" href={new URL(withSlash(enPath), Astro.site)} />
|
||||||
<link rel="alternate" hreflang="x-default" href={new URL(withSlash(zhPath), Astro.site)} />
|
<link rel="alternate" hreflang="x-default" href={new URL(withSlash(zhPath), Astro.site)} />
|
||||||
|
|||||||
Reference in new issue
Block a user