Skip to content
easy-web-worker
Interactive example · Responsiveness

The same work, without the frozen page

Run one slow computation on the main thread and then inside a Worker, and measure what the page could still do in each case.

Try it hereLive example
Application preview

Loading the example…

math.worker.ts
import { defineWorker } from 'easy-web-worker/defineWorker';
import { fibonacci } from './math';

const worker = defineWorker(() => ({ fibonacci }));

export type MathWorker = typeof worker;
Ready. Run the example to begin.Reset returns this example to its initial state.
Take it with you

Heavy work belongs on another thread. The call that starts it can still look like a function.

01

Press Run on the main thread and type in the field. Nothing appears until the work ends. Longest freeze is how long nothing could be drawn, scrolled or typed.

02

Press Run in a Worker and type again. The result is the same number, your text appears as you type, and the heartbeat keeps one bar per frame.

03

Try a larger `n`. The main-thread freeze grows with the work; the Worker version never freezes.

Read the full guide

The code

The function is ordinary TypeScript. Nothing about it knows it will run in a Worker.

math.ts
/** Deliberately slow: each extra unit of `n` roughly multiplies the work by 1.6. */
export function fibonacci(n: number): number {
  return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}

The Worker file hands that function to defineWorker and exports the type of the result.

math.worker.ts
import { defineWorker } from 'easy-web-worker/defineWorker';
import { fibonacci } from './math';

const worker = defineWorker(() => ({ fibonacci }));

export type MathWorker = typeof worker;

The main thread creates the worker from the file and gets a typed method back. Only the type is imported from the Worker file, so none of its code ends up in the main bundle.

client.ts
import { createWorker } from 'easy-web-worker/createWorker';
import workerUrl from './math.worker?worker&url';
import type { MathWorker } from './math.worker';

/** Only the type of the worker is imported here; its code is loaded by the browser as a Worker. */
export const createMathWorker = () =>
  createWorker<MathWorker>(workerUrl, {
    workerOptions: { type: 'module' },
  });

Related documentation

Keep exploring

Another piece of the model.

↑↓ Navigate ↵ Open Esc Closeeasy-web-worker docs
Get started

Real Web Workers. Typed methods.
Cancelable promises.