JSX 中异步加载字体样式表
之前在 博客网站性能优化 上调整过 webfont 加载相关逻辑,取得不错的效果。现在打算在 Publish Obsidian Vault 网页上用更加 2025 年现代的方式再实践一遍。
- Speed Up Google Fonts – CSS Wizardry
- How to Load Fonts in a Way That Fights FOUT and Makes Lighthouse Happy | CSS-Tricks
- Font style matcher
互联网上还流传有两种异步加载 CSS 的写法,使用 preload 和 使用 media ,实测它们在 Lighthouse 上的的性能一致。
<link rel="preload" as="style" crossorigin
href="https://cdn.jsdelivr.net/npm/misans-vf@1.0.0/lib/MiSans.min.css"
onload="this.onload=null;this.rel='stylesheet'" />
<link rel="stylesheet" media="print" crossorigin
href="https://cdn.jsdelivr.net/npm/misans-vf@1.0.0/lib/MiSans.min.css"
onload="this.removeAttribute('onload');this.media='all'" />在 The Simplest Way to Load CSS Asynchronously | Can’t rel=preload do this too? | Filament Group, Inc. 有解释,使用 media 的兼容性更好(但现代浏览器已经完全支持了);preload 的优先级特别高。对于字体文件,倒是希望降低优先级,所以这里我用 media 的特性。
如果只简单地将 onload=null 并不能从 HTML 中把 onload 属性去掉,所以这里我用 this.removeAttribute('onload')。
使用 preload 改造为异步加载,但是在 JSX 中做有些麻烦,不应该用 React 的 onLoad,而是 HTML 原生的 onload,得动态注入
/** 往 JSX 中添加 onload 属性 */
function preloadStylesheetOnloadFn() {
return { 'onload': "this.removeAttribute('onload');this.media='all'" };
}
function misansFontStylesheet(): JSX.Element {
return (
<>
<link rel="stylesheet" media="print" crossorigin="anonymous"
{...preloadStylesheetOnloadFn()}
href="https://registry.npmmirror.com/misans/latest/files/lib/Normal/MiSans-Medium.min.css" />
<link rel="stylesheet" media="print" crossorigin="anonymous"
{...preloadStylesheetOnloadFn()}
href="https://registry.npmmirror.com/misans/latest/files/lib/Normal/MiSans-Bold.min.css" />
</>
)
}以及如果都使用同一个 CDN,同时下载很多 WOFF2 文件会拖慢同一个 CDN 的其他资源下载队列。
经过 NPM 镜像选择 测速,选择 释放字体自由 - ZeoSeven Fonts (ZSFT) 和 npmmirror 镜像站 作为 CDN。
然后对于 MiSans,npmmirror 的速度已经比 jsdelivr 快了一倍,但切换到小米自己的 CDN 那就是天翻地覆的速度 🙂 作为小米车主,偷偷地盗个链