Remotion LabRemotion Lab
疑難排解字型載入錯誤

字型載入錯誤

解決 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 的網路請求會失敗。建議:

  1. 預先下載字型檔案並將其包含在專案中
  2. 使用 @remotion/fonts 從靜態檔案載入
  3. 或確保渲染環境可以訪問 Google Fonts CDN

相關資源