requestIdleCallbackは、ブラウザーがアイドルと判断したときにコールバックを実行するよう要求します。deadline.timeRemaining()は残り時間の推定であり、JavaScriptを途中で停止する仕組みではありません。W3C草案はコールバックの予約とdeadline インターフェースを定義しています。

時計、眠る猫、横線上に並ぶ色付きブロックを描いた概念イラスト

抽象的な時間軸の比喩です。実際のブラウザーの予定、deadline値、API実行結果ではありません。

後回しにできる処理に使う

分析データの準備や重要でないキャッシュ更新など、入力や描画を遅らせてはいけない小さな処理に使えます。アニメーション、即応性が必要な操作、必ず完了させる保存には依存しないでください。timeoutを指定しなければ、アイドル時間がないと長時間延期される可能性があります。

deadlineは推定値として扱う

コールバックのdidTimeoutはtimeout経路で実行されたかを示します。timeRemaining()は現在のアイドル機会の残り推定で、実行を強制停止する上限ではありません。長いループや同期処理はメインスレッドを塞ぎます。推定時間を途中で確認し、作業単位自体にも上限を設けます。

timeoutは完了の保証ではない

options.timeoutは、先にアイドル実行されなかった場合の代替キュー実行を求めます。スケジューリングやタイマー精度により開始が遅れることがあります。timeout経路ではdidTimeoutがtrueになり、timeRemaining()が0の場合があります。キュー全部を処理してよい合図ではないため、別途作業量を制限します。

不要な処理を取り消す

要求が返す識別子はcancelIdleCallbackに渡し、まだ実行されていないコールバックを取り消せます。ページ状態が変わって不要になった処理は停止します。対応状況を対象ブラウザーで確認し、必ず進行する必要がある処理の唯一の経路として使わないでください。

小さな処理単位に分ける

画面外の項目を段階的にindex化する例では、一度に全件を走査せず、小さな上限付きbatchを一回のコールバックで処理します。残り時間に余裕がある場合だけ次の単位へ進みます。didTimeoutがtrueでも一単位だけ実行して後続taskへ残りを回せます。アイドル予算はブラウザーが決めるため、入力件数だけで実行時間を見積もらず同期処理にも上限を設けます。

ユーザー操作で処理が不要になれば返されたhandleを使って取り消します。再予約する処理では完了・失敗をアプリ側で管理します。timeoutはコールバック開始の時刻保証でも、一連の処理全体の完了期限でもありません。特定の描画や保存までに必ず必要な処理には明示的な実行経路を設計します。

コールバックをまたぐ進行状態を管理する

処理位置と完了・失敗の状態は、コールバック内だけの一時値ではなくアプリケーション側で管理します。次の実行が遅れたり取り消されたりしても、続行するか古い処理を破棄するか判断できます。

参考資料