頁面函數執行逾時錯誤
說明 Remotion 渲染時出現 Timed out evaluating page function 錯誤的原因,通常是 CPU 或記憶體過載導致瀏覽器停止回應
頁面函數執行逾時錯誤
錯誤訊息
Error: Timed out evaluating page function
(f, c) => {
window.remotion_setFrame(f, c);
}
發生原因
此錯誤通常發生在 Remotion 渲染器嘗試向瀏覽器發送 JavaScript 指令,但瀏覽器在逾時期間內沒有回應時。
- v4.0.73 之前: 逾時為 5 秒
- v4.0.73 之後: 逾時受
--timeout旗標控制,預設為 30 秒
這表示瀏覽器因 CPU 和記憶體過載而掛起。此錯誤與 delayRender() 未清除無關。
解決方案
方案一:降低並發數量(首選)
減少同時開啟的瀏覽器標籤頁數量,降低 CPU 和記憶體壓力:
npx remotion render --concurrency=1或在程式碼中設定:
import { renderMedia } from "@remotion/renderer";
await renderMedia({
composition,
serveUrl,
codec: "h264",
outputLocation,
concurrency: 1, // 一次只渲染一幀
});對於大多數系統,建議的並發數為 CPU 核心數的一半。
方案二:監控並增加系統資源
測量渲染過程中的記憶體和 CPU 使用情況:
# macOS
top -pid $(pgrep -f "remotion")
# Linux
htop如果資源使用率接近上限,考慮:
- 升級到更高規格的機器
- 在 Lambda 環境中增加記憶體配置
- 關閉其他正在使用資源的程序
方案三:增加逾時時間
增加 --timeout 旗標的值,給予瀏覽器更多時間回應:
npx remotion render --timeout=60000 # 60 秒或在程式碼中:
await renderMedia({
composition,
serveUrl,
codec: "h264",
outputLocation,
timeoutInMilliseconds: 60000,
});注意:增加逾時時間只是延後了錯誤出現的時間,並不解決根本問題(資源過載)。應優先考慮降低並發數或增加資源。
方案四:優化 JavaScript 程式碼
找出並優化計算密集的程式碼:
// ❌ 可能造成效能問題的無限迴圈
useEffect(() => {
while (true) {
// 永不退出的迴圈
}
}, []);
// ❌ 每幀執行大量計算
const heavyResult = Array.from({ length: 1000000 }, (_, i) => i * Math.random());
// ✅ 預先計算或使用 useMemo 快取結果
const heavyResult = useMemo(() => {
return Array.from({ length: 1000000 }, (_, i) => i * Math.random());
}, []); // 只計算一次方案五:排查無限迴圈
檢查程式碼中是否存在無限迴圈:
// ❌ 狀態更新觸發重新渲染,導致無限迴圈
useEffect(() => {
setState(someValue); // 這會觸發重新渲染,再次執行 effect
}); // 沒有依賴陣列!
// ✅ 正確寫法
useEffect(() => {
setState(someValue);
}, []); // 空依賴陣列,只執行一次除錯步驟
- 降低並發數至 1 並嘗試重新渲染
- 啟用詳細日誌 觀察渲染行為:
npx remotion render --log=verbose --concurrency=1 - 在 Remotion Studio 中測試 以互動式方式確認特定幀是否有問題:
npx remotion studio - 尋找計算密集的程式碼,尤其是在
useCurrentFrame()的渲染路徑上
與其他逾時錯誤的區別
| 錯誤類型 | 原因 | 關鍵差異 |
|---|---|---|
| Timed out evaluating page function | CPU/記憶體過載,瀏覽器不回應 | 瀏覽器掛起 |
| delayRender() timeout | 非同步操作未完成 | 有 delayRender() 呼叫未清除 |
| Target closed | 瀏覽器程序崩潰 | 瀏覽器程序終止 |