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
@@ -81,7 +81,7 @@ const mmdd = (d: Date) =>
|
||||
.year {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--ink-3);
|
||||
color: var(--ink-2);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.shelf-link { float: right; font-size: 12.5px; color: var(--accent); font-weight: 400; }
|
||||
@@ -137,7 +137,7 @@ const mmdd = (d: Date) =>
|
||||
flex: none;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 12px;
|
||||
color: var(--ink-3);
|
||||
color: var(--ink-2);
|
||||
background: var(--bg-soft);
|
||||
border-radius: 5px;
|
||||
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>
|
||||
{years.map((year) => (
|
||||
<section class="year-group">
|
||||
|
||||
@@ -82,7 +82,7 @@ const first = cards[0];
|
||||
|
||||
<div class="stage">
|
||||
<ul class="wall">
|
||||
{cards.map((card) => (
|
||||
{cards.map((card, i) => (
|
||||
<li
|
||||
class="shot"
|
||||
data-group={card.group}
|
||||
@@ -103,7 +103,8 @@ const first = cards[0];
|
||||
alt={card.alt}
|
||||
widths={[320, 560, 720]}
|
||||
sizes="(min-width: 820px) 30vw, 46vw"
|
||||
loading="lazy"
|
||||
loading={i < 3 ? 'eager' : 'lazy'}
|
||||
fetchpriority={i < 3 ? 'high' : undefined}
|
||||
/>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
// 基础布局:字体/样式统一在此持有(页面不再各自引包)
|
||||
// 明暗不闪烁:ThemeScript 必须在 <head> 内联先于首帧执行
|
||||
import '@fontsource/noto-serif-sc/400.css';
|
||||
import '@fontsource/noto-serif-sc/700.css';
|
||||
import 'lxgw-wenkai-screen-webfont/lxgwwenkaiscreen.css'; // 金句点缀用(--font-kai),按需加载
|
||||
import '@fontsource/noto-sans-sc/400.css';
|
||||
import '@fontsource/noto-sans-sc/500.css';
|
||||
import '@fontsource/noto-sans-sc/700.css';
|
||||
import '@fontsource/jetbrains-mono/400.css';
|
||||
import '@fontsource/jetbrains-mono/700.css';
|
||||
// 基础布局:字体按轨瘦身 + 非阻塞加载(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';
|
||||
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 kai from 'lxgw-wenkai-screen-webfont/lxgwwenkaiscreen.css?url';
|
||||
import '../styles/global.css';
|
||||
import Header from '../components/Header.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
@@ -39,6 +39,7 @@ const withSlash = (p: string) => (p.endsWith('/') ? p : `${p}/`);
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<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="description" content={description} />
|
||||
<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>
|
||||
<ThemeScript />
|
||||
<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="en" href={new URL(withSlash(enPath), Astro.site)} />
|
||||
<link rel="alternate" hreflang="x-default" href={new URL(withSlash(zhPath), Astro.site)} />
|
||||
|
||||
Reference in new issue
Block a user