# Background Tasks API

The Background Tasks API provides the `requestIdleCallback()` method, which allows developers to queue functions to be executed during a browser's idle periods. This enables you to perform low-priority background work (like sending analytics or pre-loading data) without impacting latency-critical events such as animation and input response.

## 1. The Concept

The main thread is often busy handling user interactions and rendering. If you run a heavy task, the UI freezes. `requestIdleCallback` asks the browser: "Call me back when you aren't doing anything important."

## 2. Basic Usage

To schedule a task, pass a callback function to `requestIdleCallback()`.

```javascript
function myBackgroundTask(deadline) {
  console.log("Running in background...");
  // Do work...
}

const handle = requestIdleCallback(myBackgroundTask);
```

## 3. The `deadline` Object

The callback function receives a `deadline` object with two properties:

*   **`timeRemaining()`**: A function that returns the number of milliseconds remaining in the current idle period.
*   **`didTimeout`**: A boolean indicating if the callback is running because the timeout (if specified) was reached.

```javascript
function processData(deadline) {
  while ((deadline.timeRemaining() > 0 || deadline.didTimeout) && tasks.length > 0) {
    doWork(tasks.pop());
  }

  // If there are still tasks left, schedule another callback
  if (tasks.length > 0) {
    requestIdleCallback(processData);
  }
}
```

## 4. The `timeout` Option

You can specify a `timeout` in the options object. If the browser is too busy and the idle callback hasn't been called by this time, the browser will force it to run (even if it causes jank).

```javascript
requestIdleCallback(processData, { timeout: 2000 });
```

## 5. Canceling a Task

You can cancel a scheduled task using `cancelIdleCallback()`.

```javascript
const handle = requestIdleCallback(myBackgroundTask);

// Later...
cancelIdleCallback(handle);
```

## 6. Fallback

Not all browsers support this API (notably Safari for a long time). A simple polyfill uses `setTimeout`.

```javascript
window.requestIdleCallback = window.requestIdleCallback || function(cb) {
  return setTimeout(() => {
    cb({ didTimeout: false, timeRemaining: () => 1 });
  }, 1);
};
```

[[programming/javascript/vanilla/javascript]]
[[programming/javascript/vanilla/event-loop]]