字型載入錯誤
解決 Remotion 渲染時出現的字型載入逾時問題,尤其是使用 @remotion/google-fonts 時如何只載入需要的字型粗細和子集以避免逾時
字型載入錯誤
載入 Google Fonts 時渲染逾時
使用 @remotion/google-fonts 時,您可能遇到以下逾時錯誤:
- A delayRender() "Fetching Inter font {"style":"normal","weight":"100","subset":"cyrillic-ext"}" was called but not cleared after 58000ms.
問題原因
預設情況下,loadFont() 會嘗試載入所有可用的字型粗細(weights)和字符子集(subsets),這可能導致大量的網路請求,進而造成逾時。
例如,Inter 字型有多個粗細(100 到 900)和多個子集(latin、latin-ext、cyrillic、cyrillic-ext、greek 等),全部載入可能需要幾十個請求。
解決方案
只載入需要的字型粗細和子集
import { loadFont } from '@remotion/google-fonts/Inter';
// ❌ 避免:載入所有粗細和子集
loadFont();
// ✅ 推薦:只載入需要的粗細和子集
loadFont('normal', {
subsets: ['latin'],
weights: ['400', '700'], // 只載入標準 (400) 和粗體 (700)
});多字型的集中載入
如果您的專案使用多種字型,將字型載入集中在一個模組中,並等待所有字型載入完成後再開始渲染:
// fonts.ts
import { loadFont as loadInter } from '@remotion/google-fonts/Inter';
import { loadFont as loadRoboto } from '@remotion/google-fonts/Roboto';
import { continueRender, delayRender } from 'remotion';
export const waitForFonts = () => {
const handle = delayRender('載入字型');
Promise.all([
loadInter('normal', {
subsets: ['latin'],
weights: ['400', '700'],
}),
loadRoboto('normal', {
subsets: ['latin'],
weights: ['400'],
}),
])
.then(() => {
continueRender(handle);
})
.catch((err) => {
console.error('字型載入失敗:', err);
continueRender(handle); // 即使失敗也繼續,使用備用字型
});
};在您的根元件中使用:
// Root.tsx
import { useEffect } from 'react';
import { waitForFonts } from './fonts';
export const MyComposition: React.FC = () => {
useEffect(() => {
waitForFonts();
}, []);
return <div style={{ fontFamily: 'Inter' }}>你好世界</div>;
};字型子集說明
選擇正確的子集對效能很重要:
| 子集名稱 | 適用語言 | 說明 |
|---|---|---|
latin | 英文、西歐語言 | 最基本的拉丁字符 |
latin-ext | 東歐語言 | 擴充的拉丁字符 |
chinese-simplified | 簡體中文 | 簡體中文字符 |
chinese-traditional | 繁體中文 | 繁體中文字符 |
cyrillic | 俄文等斯拉夫語言 | 西里爾字符 |
greek | 希臘文 | 希臘字符 |
對於繁體中文內容,應載入 chinese-traditional 子集:
import { loadFont } from '@remotion/google-fonts/NotoSansTC';
loadFont('normal', {
subsets: ['chinese-traditional'],
weights: ['400', '700'],
});使用本地字型替代 Google Fonts
如果 Google Fonts 的網路請求造成問題,可以考慮使用本地字型:
// 將字型檔案放在 public/ 目錄中
import { staticFile } from 'remotion';
// 在 CSS 中使用 @font-face
const style = document.createElement('style');
style.textContent = `
@font-face {
font-family: 'MyFont';
src: url('${staticFile('fonts/my-font.woff2')}') format('woff2');
font-weight: 400;
font-style: normal;
}
`;
document.head.appendChild(style);或使用 @remotion/fonts 套件更方便地載入本地字型:
import { loadFont } from "@remotion/fonts";
import { staticFile } from "remotion";
const waitForFont = loadFont({
family: "MyFont",
url: staticFile("fonts/my-font.woff2"),
weight: "400",
style: "normal",
});離線渲染環境的注意事項
在沒有網際網路連線的環境(如 CI/CD 系統或受限網路)中渲染時,Google Fonts 的網路請求會失敗。建議:
- 預先下載字型檔案並將其包含在專案中
- 使用
@remotion/fonts從靜態檔案載入 - 或確保渲染環境可以訪問 Google Fonts CDN