fix: load Google Fonts non-blocking (prevent blank page where the CDN is blocked)#33
Merged
Conversation
…DN is blocked A render-blocking <link rel="stylesheet"> to fonts.googleapis.com holds back first paint until the request resolves. Where that host is throttled or null-routed (mainland China), the request hangs for tens of seconds and the page stays fully blank even though the JS bundle loaded and React mounted. Switch to a non-blocking load (media="print" + onload="this.media='all'") with a <noscript> blocking fallback for crawlers, so the page paints immediately with system fallback fonts and upgrades to the webfonts once (if) they arrive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Owner
Author
Code Review —
|
| 级别 | 文件 & 行号 | 描述 | 建议 |
|---|---|---|---|
| 🟡 建议 | index.html — <link media="print"> + <noscript><link> |
Google Fonts URL 被复制了两次。若字体族或字重发生变化,需同步修改两处,容易遗漏。 | 可在注释旁标注 "两处 URL 须保持同步",或考虑用 CSS 变量 / 构建脚本统一管理字体 URL。 |
| 🟢 优化 | index.html — <link rel="preconnect"> |
目前 preconnect 在 <link> 加载前已建立连接,方向正确。但若 fonts.googleapis.com 在目标区域被屏蔽,preconnect 本身也会挂起(虽然不阻塞渲染)。 |
可考虑对 preconnect 也加 crossorigin 属性一致性检查;长远方案是将字体文件自托管(self-host),从根本上消除对 Google CDN 的依赖。 |
| 🟢 优化 | index.html — <noscript> |
<noscript> 保留了阻塞式加载,适用于无 JS 客户端和爬虫。现代 Googlebot 已支持 JS,但 Baidu、Bing 部分爬虫不执行 JS,保留 <noscript> 是正确决策,无需改动。 |
— |
亮点
- 注释质量极高:清楚说明了
media="print" → onload → media='all'的工作原理、适用场景(中国大陆 CDN 封锁)和<noscript>的用途,符合项目"仅在 WHY 不明显时写注释"的规范。 - 最小变更原则:仅修改 1 个文件、1 行核心代码,附加 6 行增量,风险极低。
display=swap已就位:字体 URL 中已包含display=swap,与非阻塞加载模式配合,确保回退字体立即可见,视觉 FOUT 可控。
修改示例(可选 — DRY 改进)
若担心 URL 双写维护问题,可在 HTML 注释中标注:
<!-- FONT-URL: update BOTH the <link> below and the <noscript> copy if fonts change -->
<link rel="stylesheet"
href="`https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&display=swap"`
media="print" onload="this.media='all'">
<noscript>
<!-- FONT-URL duplicate (for no-JS crawlers) -->
<link rel="stylesheet" href="`https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&display=swap">`
</noscript>或长远方案:将字体文件下载到 frontend/public/fonts/ 并通过 @font-face 自托管,彻底解除对 Google CDN 的依赖。
Review generated post-merge for audit trail. No blocking issues found.
Generated by Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The homepage
<head>loads Google Fonts via a render-blocking<link rel="stylesheet" href="https://fonts.googleapis.com/...">. Where that host is throttled / null-routed (mainland China), the request hangs for tens of seconds and the browser holds back first paint — the page is fully blank even though the JS bundle loaded and React mounted. This matches a reported white screen (PC Chrome, China + VPN, fully blank, other overseas sites fine).Fix (
frontend/index.html)Load the webfont stylesheet non-blocking:
media="print" onload="this.media='all'", with a<noscript>blocking fallback for crawlers / no-JS clients. The page paints immediately with system fallback fonts and upgrades to the webfonts once (if) they arrive.No JS/CSS bundle change —
index-*.jshashes unchanged.