Vize

use-request-idle-callback

Run a callback in the next idle period with requestIdleCallback.

Package @vizejs/composable/use-request-idle-callback
Own the source vize lib pull composable:use-request-idle-callback
Runtime exports idle, useRequestIdleCallback
Gzip budget 2304 B

Minimal setup

Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).

vp install @vizejs/composable

Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.

import { idle, useRequestIdleCallback } from "@vizejs/composable/use-request-idle-callback";

Try it

Send analytics when the browser is idle

Defer low-priority work until the browser has nothing else to do.

Open the interactive example

What to observe: Record a click three times queues three events; they are sent together once the browser is idle.

start() schedules the callback once; calling it again while pending does nothing. A timer fallback is used where requestIdleCallback is missing.

Compare the initial and interacted states
Send analytics when the browser is idle: initial state
Initial state
Send analytics when the browser is idle: state after the verified interactions
After the verified interactions

Copy the example

Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.

<script setup lang="ts">
import { ref } from "vue";
import { useRequestIdleCallback } from "@vizejs/composable/use-request-idle-callback";

const queued = ref(0);
const sent = ref(0);
const { isPending, start } = useRequestIdleCallback(
  () => {
    sent.value += queued.value;
    queued.value = 0;
  },
  { immediate: false },
);

function track() {
  queued.value += 1;
  start();
}
</script>

<template>
  <div class="composable-example">
    <p>Send analytics events when the browser is idle instead of during interactions.</p>
    <button type="button" @click="track">Record a click</button>
    <output aria-live="polite"
      >{{ queued }} waiting · {{ sent }} sent{{ isPending ? " · flush scheduled" : "" }}</output
    >
  </div>
</template>

Runtime contract

Utility Category Stability SSR Hydration Cleanup Targets Host globals Uses
useRequestIdleCallback timing experimental deterministic-fallback caller-managed caller, reactive-scope web, desktop window tryOnScopeDispose
idle timing experimental deterministic-fallback not-applicable caller web, desktop window —

API

useRequestIdleCallback

Run a callback in the next idle period with requestIdleCallback. When the API is missing, a setTimeout fallback fabricates a deadline with a 50 ms budget and didTimeout: false. The pending callback is cancelled when the owning reactive scope stops; outside a scope the caller owns cancel(). Server rendering: nothing is scheduled, isPending and supported are false. Inside a component the first callback is scheduled after mounting, so hydration renders the server state first.

function useRequestIdleCallback( callback: (deadline: IdleDeadlineLike) => void, options: UseRequestIdleCallbackOptions = {}, ): RequestIdleCallbackControls
const { start } = useRequestIdleCallback((deadline) => {
  while (deadline.timeRemaining() > 1 && queue.length) queue.shift()?.();
}, { timeout: 2000, immediate: false });

idle

Resolve in the next idle period (or after timeout). Uses the same hosts and fallback as useRequestIdleCallback. When neither an idle host nor timers resolve (server rendering) it resolves on the next microtask with an exhausted deadline instead of hanging.

function idle(options: IdleOptions = {}): Promise<IdleDeadlineLike>
await idle({ timeout: 1000 });

Types

IdleDeadlineLike

Deadline handed to idle callbacks.

Member Type Description
didTimeout boolean Whether the callback runs because its timeout elapsed.
timeRemaining () => number Milliseconds left in the current idle period.

IdleCallbackHost

Minimal requestIdleCallback capability.

Member Type Description
requestIdleCallback (callback: (deadline: IdleDeadlineLike) => void, options?: { readonly timeout?: number }) => number Schedule callback for the next idle period.
cancelIdleCallback (handle: number) => void Cancel a scheduled callback.

IdleSchedulingOptions

Scheduling options shared by useRequestIdleCallback and idle.

Member Type Description
host? MaybeRefOrGetter<IdleCallbackHost | null | undefined> requestIdleCallback capability for alternate runtimes and tests.
timers? MaybeRefOrGetter<TimeoutScheduler | null | undefined> Timers used by the fallback when host is missing. Without timers (server rendering) nothing is scheduled.
timeout? number Run the callback after this many milliseconds even when the browser is never idle (deadline.didTimeout is then true).
now? () => number Clock used by the fallback deadline, in milliseconds.

UseRequestIdleCallbackOptions

Options for useRequestIdleCallback.

Member Type Description
host? MaybeRefOrGetter<IdleCallbackHost | null | undefined> requestIdleCallback capability for alternate runtimes and tests.
timers? MaybeRefOrGetter<TimeoutScheduler | null | undefined> Timers used by the fallback when host is missing. Without timers (server rendering) nothing is scheduled.
timeout? number Run the callback after this many milliseconds even when the browser is never idle (deadline.didTimeout is then true).
now? () => number Clock used by the fallback deadline, in milliseconds.
immediate? boolean Schedule the callback as soon as the composable is created.

IdleOptions

Options for idle.

Member Type Description
host? MaybeRefOrGetter<IdleCallbackHost | null | undefined> requestIdleCallback capability for alternate runtimes and tests.
timers? MaybeRefOrGetter<TimeoutScheduler | null | undefined> Timers used by the fallback when host is missing. Without timers (server rendering) nothing is scheduled.
timeout? number Run the callback after this many milliseconds even when the browser is never idle (deadline.didTimeout is then true).
now? () => number Clock used by the fallback deadline, in milliseconds.
signal? AbortSignal Cancels the wait; the promise rejects with signal.reason.

RequestIdleCallbackControls

Reactive state and actions returned by useRequestIdleCallback.

Member Type Description
supported ComputedRef<boolean> Whether the native requestIdleCallback API is available.
isPending Readonly<ShallowRef<boolean>> Whether a callback is scheduled and has not run yet.
start () => void Schedule the callback, replacing a pending one. No-op on the server.
cancel () => void Cancel the pending callback. Repeated calls are safe.